diff --git a/template/.gitignore b/template/_gitignore similarity index 86% rename from template/.gitignore rename to template/_gitignore index 9b838be5..16f8c307 100644 --- a/template/.gitignore +++ b/template/_gitignore @@ -1,7 +1,6 @@ # OSX # .DS_Store -*.pem # Xcode # @@ -21,7 +20,7 @@ DerivedData *.hmap *.ipa *.xcuserstate -**/.xcode.env.local +ios/.xcode.env.local # Android/IntelliJ # @@ -57,19 +56,8 @@ yarn-error.log *.jsbundle # Ruby / CocoaPods -**/Pods/ +/ios/Pods/ /vendor/bundle/ # Temporary files created by Metro to check the health of the file watcher .metro-health-check* - -# testing -/coverage - -# Yarn -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions \ No newline at end of file diff --git a/template/metro.config.js b/template/metro.config.js index de3148ee..e2635403 100644 --- a/template/metro.config.js +++ b/template/metro.config.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config') /** diff --git a/template/scripts/build-app.sh b/template/scripts/build-app.sh index cfe30ef2..f3f67f35 100644 --- a/template/scripts/build-app.sh +++ b/template/scripts/build-app.sh @@ -19,7 +19,7 @@ function buildApp() { function main() { if [ -z $TYPE ]; then - read -p 'Enter your environment (dev,staging,production): ' env + read -p 'Enter your environment (development,staging,production): ' env TYPE=$env fi diff --git a/template/scripts/code-push.sh b/template/scripts/code-push.sh index 3b611fb2..55d488fe 100644 --- a/template/scripts/code-push.sh +++ b/template/scripts/code-push.sh @@ -20,7 +20,7 @@ function codePush() { function main() { if [ -z $TYPE ]; then - read -p 'Enter your environment: ' env + read -p 'Enter your environment (development, staging, production): ' env TYPE=$env fi diff --git a/template/src/components/Toast.tsx b/template/src/components/Toast.tsx index db87eb18..9ad73c21 100644 --- a/template/src/components/Toast.tsx +++ b/template/src/components/Toast.tsx @@ -90,12 +90,11 @@ export const Toast: React.FC = () => { const dismiss = () => { animationRef.current?.stop() - setState(initState) Animated.timing(animation, { toValue: 0, duration: DEFAULT_DURATION, useNativeDriver: true, - }).start() + }).start(() => setState(initState)) } useEffect(() => { diff --git a/template/src/navigation/NavigationService.tsx b/template/src/navigation/NavigationService.tsx index bfb6cc69..d96cc56b 100644 --- a/template/src/navigation/NavigationService.tsx +++ b/template/src/navigation/NavigationService.tsx @@ -19,7 +19,7 @@ export const getParent = (): NavigationProp | null => export const navigate = ( name: keyof AppStackParamList, - params: AppStackParamList[keyof AppStackParamList], + params?: AppStackParamList[keyof AppStackParamList], ) => { if (navigationRef.isReady()) { navigationRef.navigate(name as string, params as object | undefined) diff --git a/template/src/navigation/StackNavigation.tsx b/template/src/navigation/StackNavigation.tsx index 6bf3ea09..76705dd4 100644 --- a/template/src/navigation/StackNavigation.tsx +++ b/template/src/navigation/StackNavigation.tsx @@ -1,7 +1,6 @@ import {createNativeStackNavigator} from '@react-navigation/native-stack' import React from 'react' -import {LoginScreen, SignUpScreen} from '../screens' -import HomeScreen from '../screens/HomeComponent/HomeScreen' +import {HomeScreen, LoginScreen, SignUpScreen} from '../screens' import RouteKey from './RouteKey' import {optionsMatch} from './ScreenService' import {AppStackParamList} from './types' diff --git a/template/src/screens/AuthComponent/LoginScreen.tsx b/template/src/screens/AuthComponent/LoginScreen.tsx index 195279f8..bf0707eb 100644 --- a/template/src/screens/AuthComponent/LoginScreen.tsx +++ b/template/src/screens/AuthComponent/LoginScreen.tsx @@ -1,9 +1,9 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack' -import React, {PropsWithChildren} from 'react' +import React from 'react' import {ScreenContainer} from '../../components' import RouteKey from '../../navigation/RouteKey' import {AppStackParamList} from '../../navigation/types' -type Props = NativeStackScreenProps & PropsWithChildren +type Props = NativeStackScreenProps -export const LoginScreen: React.FC = props => {props.children} +export const LoginScreen: React.FC = () => diff --git a/template/src/screens/AuthComponent/SignUpScreen.tsx b/template/src/screens/AuthComponent/SignUpScreen.tsx index 94122765..570b4ce7 100644 --- a/template/src/screens/AuthComponent/SignUpScreen.tsx +++ b/template/src/screens/AuthComponent/SignUpScreen.tsx @@ -1,9 +1,9 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack' -import React, {PropsWithChildren} from 'react' +import React from 'react' import {ScreenContainer} from '../../components' import RouteKey from '../../navigation/RouteKey' import {AppStackParamList} from '../../navigation/types' -type Props = NativeStackScreenProps & PropsWithChildren +type Props = NativeStackScreenProps -export const SignUpScreen: React.FC = props => {props.children} +export const SignUpScreen: React.FC = () => diff --git a/template/src/screens/HomeComponent/HomeScreen.tsx b/template/src/screens/HomeComponent/HomeScreen.tsx index fab66b6e..4598fbbe 100644 --- a/template/src/screens/HomeComponent/HomeScreen.tsx +++ b/template/src/screens/HomeComponent/HomeScreen.tsx @@ -1,11 +1,9 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack' -import React, {PropsWithChildren} from 'react' +import React from 'react' import {ScreenContainer} from '../../components' import RouteKey from '../../navigation/RouteKey' import {AppStackParamList} from '../../navigation/types' -type Props = NativeStackScreenProps & PropsWithChildren +type Props = NativeStackScreenProps -const HomeScreen: React.FC = props => {props.children} - -export default HomeScreen +export const HomeScreen: React.FC = () => diff --git a/template/src/screens/SplashScreen.tsx b/template/src/screens/SplashScreen.tsx index 86d307f4..d9bcd5d1 100644 --- a/template/src/screens/SplashScreen.tsx +++ b/template/src/screens/SplashScreen.tsx @@ -1,21 +1,28 @@ import React, {useEffect, useState} from 'react' -import {StyleSheet, View} from 'react-native' +import {StyleSheet, Text, View} from 'react-native' import CodePush from 'react-native-code-push' -import Progress from 'react-native-progress' +import * as Progress from 'react-native-progress' import {ScreenContainer} from '../components' import configs from '../constants/configs' import {appActions} from '../store/reducers/app' -import {useAppDispatch} from '../store/store' -import {colors, deviceWidth, responsiveHeight} from '../themes' +import {useDispatch} from 'react-redux' +import {colors, deviceWidth, metrics, responsiveHeight} from '../themes' const codePushOptions = { installMode: CodePush.InstallMode.IMMEDIATE, deploymentKey: configs.codePushKey, } +const STATUS = { + check: 'Checking for update', + download: 'Downloading...', + done: 'Done', +} + const SplashScreen = () => { - const dispatch = useAppDispatch() + const dispatch = useDispatch() const [updatePercent, setUpdatePercent] = useState(0) + const [statusText, setStatusText] = useState('') useEffect(() => { CodePush.sync( @@ -26,11 +33,22 @@ const SplashScreen = () => { case CodePush.SyncStatus.UNKNOWN_ERROR: dispatch(appActions.getSettings()) break + case CodePush.SyncStatus.DOWNLOADING_PACKAGE: + case CodePush.SyncStatus.INSTALLING_UPDATE: + case CodePush.SyncStatus.SYNC_IN_PROGRESS: + setStatusText(STATUS.download) + break + default: + setStatusText(STATUS.check) } }, ({receivedBytes, totalBytes}) => { + const percent = receivedBytes / totalBytes if (totalBytes > 0) { - setUpdatePercent(receivedBytes / totalBytes) + setUpdatePercent(percent) + } + if (percent === 1) { + setStatusText(STATUS.done) } }, ).catch(() => { @@ -43,6 +61,7 @@ const SplashScreen = () => { {updatePercent > 0 ? ( + {statusText} ) : null} @@ -58,6 +77,11 @@ const styles = StyleSheet.create({ position: 'absolute', bottom: responsiveHeight(40), alignSelf: 'center', + alignItems: 'center', + }, + progressText: { + color: colors.primary, + paddingTop: metrics.xxs, }, }) diff --git a/template/src/store/store.ts b/template/src/store/store.ts index 048ecb59..2c7fadf9 100644 --- a/template/src/store/store.ts +++ b/template/src/store/store.ts @@ -1,5 +1,5 @@ -import {applyMiddleware, configureStore, Reducer} from '@reduxjs/toolkit' -import {useDispatch, useSelector as useReduxSelector} from 'react-redux' +import {applyMiddleware, configureStore} from '@reduxjs/toolkit' +import {useSelector as useReduxSelector} from 'react-redux' import type {TypedUseSelectorHook} from 'react-redux' import {persistReducer, persistStore} from 'redux-persist' import reducers, {persistConfig} from './reducers' @@ -15,9 +15,7 @@ const persistedReducer = persistReducer(persistConfig, reducers) const store = configureStore({ reducer: persistedReducer, middleware: getDefaultMiddleware => getDefaultMiddleware({serializableCheck: false, thunk: false}), - enhancers: (getDefaultEnhancers) => { - return getDefaultEnhancers().concat(middlewareEnhancer) - }, + enhancers: getDefaultEnhancers => getDefaultEnhancers().concat(middlewareEnhancer), }) sagaMiddleware.run(rootSaga) @@ -27,7 +25,6 @@ const persistor = persistStore(store) export type AppDispatch = typeof store.dispatch export type AppState = typeof store.getState export type RootState = ReturnType -export const useAppDispatch: () => AppDispatch = useDispatch export const useSelector: TypedUseSelectorHook = useReduxSelector export {store, persistor} diff --git a/template/src/utilities/Emitter.ts b/template/src/utilities/Emitter.ts index d3d4b6c9..66792a58 100644 --- a/template/src/utilities/Emitter.ts +++ b/template/src/utilities/Emitter.ts @@ -7,7 +7,7 @@ class EventRegister { refs: {key: {eventName: '', callback: () => {}}}, } - static addEventListener(eventName: string, callback: (param: any) => void): string { + static addEventListener(eventName: string, callback: (param?: any) => void): string { EventRegister._Listeners.count += 1 const eventId = `l${EventRegister._Listeners.count}` EventRegister._Listeners.refs[eventId] = { @@ -30,7 +30,7 @@ class EventRegister { return !removeError } - static emitEvent(eventName: string, param: any): void { + static emitEvent(eventName: string, param?: any): void { Object.keys(EventRegister._Listeners.refs).forEach(_id => { if (EventRegister._Listeners.refs[_id] && eventName === EventRegister._Listeners.refs[_id].eventName) { EventRegister._Listeners.refs[_id].callback(param) @@ -41,7 +41,7 @@ class EventRegister { /* * Shorten */ - static on(eventName: string, callback: (param: any) => void): string { + static on(eventName: string, callback: (param?: any) => void): string { return EventRegister.addEventListener(eventName, callback) } @@ -53,7 +53,7 @@ class EventRegister { return EventRegister.removeAllListeners() } - static emit(eventName: string, param: any): void { + static emit(eventName: string, param?: any): void { EventRegister.emitEvent(eventName, param) } }