diff --git a/.eslintrc.js b/.eslintrc.js index 187894b..dbd4b8a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,14 @@ module.exports = { root: true, extends: '@react-native', + rules: { + 'react/react-in-jsx-scope': 'off', + 'react-native/no-inline-styles': 0, + 'prettier/prettier': [ + 'error', + { + 'no-inline-styles': false, + }, + ], + }, }; diff --git a/.vscode/settings.json b/.vscode/settings.json index 4f81299..723db17 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { - "java.configuration.updateBuildConfiguration": "automatic" + "java.configuration.updateBuildConfiguration": "automatic", + "java.compile.nullAnalysis.mode": "automatic", + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/App.js b/App.js deleted file mode 100644 index 02d5cdb..0000000 --- a/App.js +++ /dev/null @@ -1,339 +0,0 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; -import React, {useEffect, useRef, useState} from 'react'; -import { - Alert, - Animated, - AppRegistry, - BackHandler, - Dimensions, - Image, - Linking, - PermissionsAndroid, - Platform, - SafeAreaView, - StatusBar, - Text, - TouchableOpacity, - View, -} from 'react-native'; -import {ExpandingDot} from 'react-native-animated-pagination-dots'; -import * as RNLocalize from 'react-native-localize'; -import {PERMISSIONS, request} from 'react-native-permissions'; -import SplashScreen from 'react-native-splash-screen'; -import {SwiperFlatList} from 'react-native-swiper-flatlist'; -import {WebView} from 'react-native-webview'; -import Bubble1SVG from './image/bubble1.svg'; -import Bubble1enSVG from './image/bubble1en.svg'; -import Bubble2SVG from './image/bubble2.svg'; -import Bubble2enSVG from './image/bubble2en.svg'; -import Text1SVG from './image/text1.svg'; -import Text1enSVG from './image/text1en.svg'; -import Text2SVG from './image/text2.svg'; -import Text2enSVG from './image/text2en.svg'; -import messaging from '@react-native-firebase/messaging'; - -// Firebase 알림 -async function requestUserPermission() { - const authStatus = await messaging().requestPermission(); - const enabled = - authStatus === messaging.AuthorizationStatus.AUTHORIZED || - authStatus === messaging.AuthorizationStatus.PROVISIONAL; - - if (enabled) { - console.log('Authorization status:', authStatus); - } -} - -const deviceWidth = Dimensions.get('window').width; - -const imageDataList = [ - {no: 1, uri: require('./image/character_edit.png')}, - {no: 2, uri: require('./image/character_edit2.png')}, - {no: 3, uri: require('./image/start.png')}, -]; - -const SOURCE_URL = 'https://gloddy.vercel.app'; - -export default function App() { - const webViewRef = useRef(); - const [lang, setlang] = useState(null); - const scrollX = useRef(new Animated.Value(0)).current; - const [webloading, setwebloading] = useState(true); - const [showindex, setshowindex] = useState(true); - - // 앱이 Foreground 인 상태에서 푸쉬알림 받는 코드 작성 - useEffect(() => { - const unsubscribe = messaging().onMessage(async remoteMessage => { - Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage)); - }); - - return unsubscribe; - }, []); - - // 앱이 Background 이거나 꺼진 상태에서 푸쉬알림 받는 코드 작성 - messaging().setBackgroundMessageHandler(async remoteMessage => { - console.log('Message handled in the background!', remoteMessage); - }); - - AppRegistry.registerComponent('app', () => App); - - const onShouldStartLoadWithRequest = event => { - if (!event.url.includes(SOURCE_URL)) { - Linking.openURL(event.url); - return false; - } - return true; - }; - - const sendweb = () => { - try { - const lang = RNLocalize.getLocales()[0].languageCode; - const payload = { - type: 'RNLocalize', - Platform: Platform.OS, - data: lang, - }; - webViewRef.current.postMessage(JSON.stringify(payload)); - } catch (error) { - console.log(error); - } - }; - - // 뒤로 가기 control - const [exit, setexit] = useState(false); - const [swexit, setswexit] = useState(0); - const backAction = () => { - // 500(0.5초) 안에 back 버튼을 한번 더 클릭 할 경우 앱 종료 - setswexit(swexit => swexit + 1); - return true; - }; - useEffect(() => { - let timer; - if (exit === false) { - webViewRef?.current?.goBack(); - setexit(true); - timer = setTimeout(function () { - setexit(false); - }, 500); - } else { - clearTimeout(timer); - BackHandler.exitApp(); - } - }, [swexit]); - useEffect(() => { - BackHandler.addEventListener('hardwareBackPress', backAction); - - return () => - BackHandler.removeEventListener('hardwareBackPress', backAction); - }, []); - - const preloading = async () => { - const lang = RNLocalize.getLocales()[0].languageCode; - setlang(lang); - const get = await AsyncStorage.getItem('token'); - if (get) { - setwebloading(false); - } - }; - useEffect(() => { - preloading(); - setTimeout(() => { - SplashScreen.hide(); - }, 3000); - }, []); - - // 사진 라이브러리를 사용하기 전에 이 함수를 호출해야 합니다. - // 권한설정 - - useEffect(() => { - if (Platform.OS === 'android') { - const getper = async () => { - await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.ACCESS_MEDIA_LOCATION, - ); - await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA); - }; - getper(); - } - if (Platform.OS === 'ios') { - const requestPhotoLibraryPermission = async () => { - await request(PERMISSIONS.IOS.CAMERA); - await request(PERMISSIONS.IOS.MICROPHONE); - await request(PERMISSIONS.IOS.PHOTO_LIBRARY); - await requestUserPermission(); - }; - requestPhotoLibraryPermission(); - } - }, []); - - const onMessageReceived = async event => { - if (event.nativeEvent.data === 'signout') { - await AsyncStorage.removeItem('token'); - setwebloading(true); - } - }; - - const handlestart = async () => { - await AsyncStorage.setItem('token', 'ok'); - setwebloading(false); - }; - - const onNavigationStateChange = navState => { - webViewRef.canGoBack = navState.canGoBack; - if (!navState.url.includes(SOURCE_URL)) { - Linking.openURL(navState.url); - return false; - } - }; - - return ( - - {webloading ? ( - - setshowindex(e.index)} - horizontal={true} - onScroll={Animated.event( - [{nativeEvent: {contentOffset: {x: scrollX}}}], - { - useNativeDriver: false, - }, - )} - onContentProcessDidTerminate={() => webViewRef.current.reload()} - data={imageDataList} - renderItem={({item, index}) => { - return ( - - {index === 0 ? ( - - {lang === 'ko' ? : } - - {lang === 'ko' ? : } - - ) : index === 1 ? ( - - {lang === 'ko' ? : } - - {lang === 'ko' ? : } - - ) : ( - - )} - - {index === 2 && ( - { - handlestart(); - }} - style={{ - width: deviceWidth * 0.9, - height: 60, - borderRadius: 10, - backgroundColor: 'rgb(75,133,247)', - justifyContent: 'center', - alignItems: 'center', - }}> - - {lang === 'ko' ? '시작하기' : 'START'} - - - )} - - ); - }} - keyExtractor={(item, index) => String(index)} - /> - {showindex !== 2 && ( - - )} - - ) : ( - - sendweb()} - onMessage={onMessageReceived} - // 웹뷰 로딩이 시작되거나 끝나면 호출하는 함수 navState로 url 감지 - onNavigationStateChange={onNavigationStateChange} - // 처음 호출한 URL에서 다시 Redirect하는 경우에, 사용하면 navState url 감지 - onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} - /> - - )} - - - ); -} diff --git a/App.tsx b/App.tsx new file mode 100644 index 0000000..3f45554 --- /dev/null +++ b/App.tsx @@ -0,0 +1,20 @@ +import MainNavigator from './src/components/MainNavigator'; +import React from 'react'; +import {StatusBar, View} from 'react-native'; + +export default function App() { + return ( + <> +