Browse Source

FEATURE| Async storage and game layouts | Games module

merge-requests/5/head
JetUp 2 years ago
parent
commit
ffe6918fef
  1. 6
      ios/Podfile.lock
  2. 173
      package-lock.json
  3. 2
      package.json
  4. BIN
      src/assets/image/addPlus.png
  5. BIN
      src/assets/image/circleArrows.png
  6. BIN
      src/assets/image/magic-star.png
  7. BIN
      src/assets/image/play.png
  8. 20
      src/module/root/atoms/premium-button.component.tsx
  9. 16
      src/module/root/navigations-groups/on-boardings-group.tsx
  10. 59
      src/module/root/screens/game.tsx
  11. 7
      src/module/root/screens/language-select.screen.tsx
  12. 61
      src/module/root/screens/loading-screen.tsx
  13. 5
      src/module/root/screens/on-boarding.screen.tsx
  14. 100
      src/module/root/screens/questions.tsx
  15. 46
      src/module/services/async-storage.service.ts
  16. 4
      src/module/shared/colors/colors.ts
  17. 10
      src/module/shared/components/buttons/primary-btn.component.tsx
  18. 32
      src/module/shared/components/buttons/red-button.tsx
  19. 22
      src/module/shared/components/header/header.component.tsx
  20. 124
      src/module/shared/components/modals/main-modal.tsx
  21. 25
      src/module/shared/components/nameTitle/name-title.tsx
  22. 37
      src/module/shared/components/questionBlock/question-block.tsx
  23. 3
      src/module/shared/enums/route-keys.ts

6
ios/Podfile.lock

@ -345,6 +345,8 @@ PODS: @@ -345,6 +345,8 @@ PODS:
- React-jsi (= 0.67.4)
- React-logger (= 0.67.4)
- React-perflogger (= 0.67.4)
- RNCAsyncStorage (1.17.11):
- React-Core
- RNGestureHandler (2.5.0):
- React-Core
- RNScreens (3.15.0):
@ -412,6 +414,7 @@ DEPENDENCIES: @@ -412,6 +414,7 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`)
@ -497,6 +500,8 @@ EXTERNAL SOURCES: @@ -497,6 +500,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNCAsyncStorage:
:path: "../node_modules/@react-native-async-storage/async-storage"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
RNScreens:
@ -551,6 +556,7 @@ SPEC CHECKSUMS: @@ -551,6 +556,7 @@ SPEC CHECKSUMS:
React-RCTVibration: 3b52a7dced19cdb025b4f88ab26ceb2d85f30ba2
React-runtimeexecutor: a9d3c82ddf7ffdad9fbe6a81c6d6f8c06385464d
ReactCommon: 07d0c460b9ba9af3eaf1b8f5abe7daaad28c9c4e
RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60
RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50
RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7
RNSVG: ecd661f380a07ba690c9c5929c475a44f432d674

173
package-lock.json generated

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
"name": "truth",
"version": "0.0.1",
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.11",
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"i18next": "^21.8.14",
@ -16,6 +17,7 @@ @@ -16,6 +17,7 @@
"react": "17.0.2",
"react-i18next": "^11.18.1",
"react-native": "^0.67.4",
"react-native-animated-loader": "^1.0.0",
"react-native-gesture-handler": "^2.5.0",
"react-native-icomoon": "^0.1.1",
"react-native-safe-area-context": "^4.3.1",
@ -2776,6 +2778,17 @@ @@ -2776,6 +2778,17 @@
"node": ">= 8"
}
},
"node_modules/@react-native-async-storage/async-storage": {
"version": "1.17.11",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz",
"integrity": "sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw==",
"dependencies": {
"merge-options": "^3.0.4"
},
"peerDependencies": {
"react-native": "^0.0.0-0 || 0.60 - 0.71 || 1000.0.0"
}
},
"node_modules/@react-native-community/cli-debugger-ui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-6.0.0.tgz",
@ -6283,6 +6296,12 @@ @@ -6283,6 +6296,12 @@
"node": ">=8"
}
},
"node_modules/dedent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz",
"integrity": "sha512-cSfRWjXJtZQeRuZGVvDrJroCR5V2UvBNUMHsPCdNYzuAG8b9V8aAy3KUcdQrGQPXs17Y+ojbPh1aOCplg9YR9g==",
"peer": true
},
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -6369,6 +6388,17 @@ @@ -6369,6 +6388,17 @@
"node": ">= 0.8"
}
},
"node_modules/deprecated-react-native-prop-types": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz",
"integrity": "sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==",
"peer": true,
"dependencies": {
"@react-native/normalize-color": "*",
"invariant": "*",
"prop-types": "*"
}
},
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@ -8772,6 +8802,14 @@ @@ -8772,6 +8802,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"engines": {
"node": ">=8"
}
},
"node_modules/is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@ -11056,6 +11094,33 @@ @@ -11056,6 +11094,33 @@
"loose-envify": "cli.js"
}
},
"node_modules/lottie-ios": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/lottie-ios/-/lottie-ios-3.5.0.tgz",
"integrity": "sha512-DM6BYLhHTzvUsK89AjY+K9RwVGkOBwbH/iytjyZUmFbXz8DVsoPEyy+c7L5NZmVouZHvLnOQp6NaYTkwMo+iOg==",
"peer": true
},
"node_modules/lottie-react-native": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-5.1.5.tgz",
"integrity": "sha512-xl6uEo50joQeIqso5SvPKt1uGBqMhgNgs+36S4725Nfigf4zAY23/I9QEEkJF+1BHq7wKCeYha2KafLTm20gqA==",
"peer": true,
"dependencies": {
"invariant": "^2.2.2",
"react-native-safe-modules": "^1.0.3"
},
"peerDependencies": {
"lottie-ios": "^3.4.0",
"react": "*",
"react-native": ">=0.46",
"react-native-windows": ">=0.63.x"
},
"peerDependenciesMeta": {
"react-native-windows": {
"optional": true
}
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -11115,6 +11180,17 @@ @@ -11115,6 +11180,17 @@
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
"node_modules/merge-options": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
"dependencies": {
"is-plain-obj": "^2.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -12937,6 +13013,20 @@ @@ -12937,6 +13013,20 @@
"react": "17.0.2"
}
},
"node_modules/react-native-animated-loader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-native-animated-loader/-/react-native-animated-loader-1.0.0.tgz",
"integrity": "sha512-XI4xk5SQr8BX+qUF9yL2RpoALYmMk4kt233PtOl1o7iUrR/jyXWpZ7+iwHDitV6Q+WB+obxzK6dyf/XtMPIVfQ==",
"dependencies": {
"prop-types": "^15.6.2"
},
"peerDependencies": {
"deprecated-react-native-prop-types": "^2.3.0",
"lottie-react-native": ">=3.0.0",
"react": "*",
"react-native": ">=0.46"
}
},
"node_modules/react-native-codegen": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.8.tgz",
@ -12981,6 +13071,18 @@ @@ -12981,6 +13071,18 @@
"react-native": "*"
}
},
"node_modules/react-native-safe-modules": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-native-safe-modules/-/react-native-safe-modules-1.0.3.tgz",
"integrity": "sha512-DUxti4Z+AgJ/ZsO5U7p3uSCUBko8JT8GvFlCeOXk9bMd+4qjpoDvMYpfbixXKgL88M+HwmU/KI1YFN6gsQZyBA==",
"peer": true,
"dependencies": {
"dedent": "^0.6.0"
},
"peerDependencies": {
"react-native": "*"
}
},
"node_modules/react-native-screens": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.15.0.tgz",
@ -18310,6 +18412,14 @@ @@ -18310,6 +18412,14 @@
"fastq": "^1.6.0"
}
},
"@react-native-async-storage/async-storage": {
"version": "1.17.11",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz",
"integrity": "sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw==",
"requires": {
"merge-options": "^3.0.4"
}
},
"@react-native-community/cli-debugger-ui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-6.0.0.tgz",
@ -20900,6 +21010,12 @@ @@ -20900,6 +21010,12 @@
"mimic-response": "^2.0.0"
}
},
"dedent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz",
"integrity": "sha512-cSfRWjXJtZQeRuZGVvDrJroCR5V2UvBNUMHsPCdNYzuAG8b9V8aAy3KUcdQrGQPXs17Y+ojbPh1aOCplg9YR9g==",
"peer": true
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -20965,6 +21081,17 @@ @@ -20965,6 +21081,17 @@
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
},
"deprecated-react-native-prop-types": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz",
"integrity": "sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==",
"peer": true,
"requires": {
"@react-native/normalize-color": "*",
"invariant": "*",
"prop-types": "*"
}
},
"destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@ -22751,6 +22878,11 @@ @@ -22751,6 +22878,11 @@
"has-tostringtag": "^1.0.0"
}
},
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
},
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@ -24483,6 +24615,22 @@ @@ -24483,6 +24615,22 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"lottie-ios": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/lottie-ios/-/lottie-ios-3.5.0.tgz",
"integrity": "sha512-DM6BYLhHTzvUsK89AjY+K9RwVGkOBwbH/iytjyZUmFbXz8DVsoPEyy+c7L5NZmVouZHvLnOQp6NaYTkwMo+iOg==",
"peer": true
},
"lottie-react-native": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-5.1.5.tgz",
"integrity": "sha512-xl6uEo50joQeIqso5SvPKt1uGBqMhgNgs+36S4725Nfigf4zAY23/I9QEEkJF+1BHq7wKCeYha2KafLTm20gqA==",
"peer": true,
"requires": {
"invariant": "^2.2.2",
"react-native-safe-modules": "^1.0.3"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -24527,6 +24675,14 @@ @@ -24527,6 +24675,14 @@
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
"merge-options": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
"requires": {
"is-plain-obj": "^2.1.0"
}
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -26145,6 +26301,14 @@ @@ -26145,6 +26301,14 @@
}
}
},
"react-native-animated-loader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-native-animated-loader/-/react-native-animated-loader-1.0.0.tgz",
"integrity": "sha512-XI4xk5SQr8BX+qUF9yL2RpoALYmMk4kt233PtOl1o7iUrR/jyXWpZ7+iwHDitV6Q+WB+obxzK6dyf/XtMPIVfQ==",
"requires": {
"prop-types": "^15.6.2"
}
},
"react-native-codegen": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.8.tgz",
@ -26179,6 +26343,15 @@ @@ -26179,6 +26343,15 @@
"integrity": "sha512-cEr7fknJCToTrSyDCVNg0GRdRMhyLeQa2NZwVCuzEQcWedOw/59ExomjmzCE4rxrKXs6OJbyfNtFRNyewDaHuA==",
"requires": {}
},
"react-native-safe-modules": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-native-safe-modules/-/react-native-safe-modules-1.0.3.tgz",
"integrity": "sha512-DUxti4Z+AgJ/ZsO5U7p3uSCUBko8JT8GvFlCeOXk9bMd+4qjpoDvMYpfbixXKgL88M+HwmU/KI1YFN6gsQZyBA==",
"peer": true,
"requires": {
"dedent": "^0.6.0"
}
},
"react-native-screens": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.15.0.tgz",

2
package.json

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.11",
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"i18next": "^21.8.14",
@ -23,6 +24,7 @@ @@ -23,6 +24,7 @@
"react": "17.0.2",
"react-i18next": "^11.18.1",
"react-native": "^0.67.4",
"react-native-animated-loader": "^1.0.0",
"react-native-gesture-handler": "^2.5.0",
"react-native-icomoon": "^0.1.1",
"react-native-safe-area-context": "^4.3.1",

BIN
src/assets/image/addPlus.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

BIN
src/assets/image/circleArrows.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

BIN
src/assets/image/magic-star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

BIN
src/assets/image/play.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

20
src/module/root/atoms/premium-button.component.tsx

@ -1,5 +1,9 @@ @@ -1,5 +1,9 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useNavigation } from '@react-navigation/native';
import { navigate } from '@react-navigation/routers/lib/typescript/src/CommonActions';
import React, {FC} from 'react';
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import { StorageKey, storageService } from '../../services/async-storage.service';
import {colors, IRouteParams, PrimaryBtn, RouteKey} from '../../shared';
interface IProps {
currentIndex: number;
@ -17,17 +21,29 @@ interface IProps { @@ -17,17 +21,29 @@ interface IProps {
) => void;
}
export const GroupBtn: FC<IProps> = ({currentIndex, data, onPressItem}) => {
const navigation = useNavigation();
if (data.length - 1 === currentIndex) {
return (
<View style={styles.btncontainer}>
<PrimaryBtn
onPress={() => {}}
onPress={async () => {
await AsyncStorage.setItem(StorageKey.OnBoarding, 'true');
navigation.navigate(RouteKey.Game as any);
console.log('last buttons')
}}
children={<Text style={styles.text}>{`Open now / $4.99`}</Text>}
width={190}
/>
<TouchableOpacity
style={styles.laterBtn}
onPress={() => console.log('press')}>
onPress={ async () =>{
await AsyncStorage.setItem(StorageKey.OnBoarding, 'true');
navigation.navigate(RouteKey.Game as any);
console.log('last buttons')
}
}>
<Text style={[styles.text, {fontWeight: '400'}]}>Later</Text>
</TouchableOpacity>
</View>

16
src/module/root/navigations-groups/on-boardings-group.tsx

@ -1,8 +1,12 @@ @@ -1,8 +1,12 @@
import React, {FC} from 'react';
import React, {FC, useEffect, useState} from 'react';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {RouteKey} from '../../shared';
import {LanguageSelect, Onboarding, Setting} from '../screens';
import {SelectPackages} from '../../game/screen/select-packages.screen';
import {LoadingScreen} from '../screens/loading-screen';
import {Game} from '../screens/game';
import { Questions } from '../screens/questions';
const Stack = createNativeStackNavigator();
export const OnboardingGroup: FC = () => {
return (
@ -10,11 +14,15 @@ export const OnboardingGroup: FC = () => { @@ -10,11 +14,15 @@ export const OnboardingGroup: FC = () => {
screenOptions={{
headerShown: false,
}}
initialRouteName={RouteKey.Game}>
<Stack.Screen name={RouteKey.LanguageSelect} component={LanguageSelect} />
<Stack.Screen name={RouteKey.Setting} component={Setting} />
initialRouteName={RouteKey.Loading}
>
<Stack.Screen name={RouteKey.Questions} component={Questions} />
<Stack.Screen name={RouteKey.Package} component={Game} />
<Stack.Screen name={RouteKey.Onboarding} component={Onboarding} />
<Stack.Screen name={RouteKey.Loading} component={LoadingScreen} />
<Stack.Screen name={RouteKey.LanguageSelect} component={LanguageSelect} />
<Stack.Screen name={RouteKey.Game} component={SelectPackages} />
<Stack.Screen name={RouteKey.Setting} component={Setting} />
</Stack.Navigator>
);
};

59
src/module/root/screens/game.tsx

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import {
colors,
Header,
RouteKey,
ScreenLayout,
IRouteParams,
} from '../../shared';
import React from 'react';
import {NameTitle} from '../../shared/components/nameTitle/name-title';
import {RedButton} from '../../shared/components/buttons/red-button';
interface IProps extends IRouteParams {}
export const Game: React.FC<IProps> = ({navigation}) => {
const goBack = () => {
navigation.navigate(RouteKey.Game);
};
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
backgroundStatusBar={colors.primaryColor}
paddingHorizontal={20}>
<>
<Header
leftIcon="arrow"
gamer={true}
onPressLeft={() => goBack()}
title="Crazy"
/>
<NameTitle name="Player" />
<View style={styles.buttons}>
<RedButton name="-TRUTH-" />
<TouchableOpacity>
<Text style={styles.random}>
RANDOM CHANCE
</Text>
</TouchableOpacity>
<RedButton name="-DARE-" />
</View>
</>
</ScreenLayout>
);
};
const styles = StyleSheet.create({
buttons: {
alignItems: 'center',
height: 240,
justifyContent: 'space-between',
marginTop: 122
},
random: {
color: '#ffffff',
fontWeight: '400',
fontSize: 18,
}
});

7
src/module/root/screens/language-select.screen.tsx

@ -1,7 +1,9 @@ @@ -1,7 +1,9 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import React, {FC} from 'react';
import {useTranslation} from 'react-i18next';
import {Image, StyleSheet, Text, View} from 'react-native';
import {LangKeys} from '../../../i18n';
import { StorageKey, storageService } from '../../services/async-storage.service';
import {IRouteParams, RouteKey, colors, ScreenLayout} from '../../shared';
import {LanguageItem} from '../components';
const languageArr = [
@ -25,6 +27,8 @@ interface IProps extends IRouteParams {} @@ -25,6 +27,8 @@ interface IProps extends IRouteParams {}
export const LanguageSelect: FC<IProps> = ({navigation}) => {
const {t, i18n} = useTranslation();
console.log('before', i18n.language);
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
@ -34,9 +38,10 @@ export const LanguageSelect: FC<IProps> = ({navigation}) => { @@ -34,9 +38,10 @@ export const LanguageSelect: FC<IProps> = ({navigation}) => {
{languageArr.map(el => (
<LanguageItem
key={el.name}
onPress={() => {
onPress={async () => {
navigation.navigate(RouteKey.Onboarding);
i18n.changeLanguage(el.key);
await AsyncStorage.setItem(StorageKey.Language, el.key);
}}
icon={el.icon}
name={el.name}

61
src/module/root/screens/loading-screen.tsx

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
import {
ActivityIndicator,
Animated,
StyleSheet,
Text,
View,
} from 'react-native';
import React, {FC, useEffect, useState} from 'react';
import {ScreenLayout, colors, RouteKey} from '../../shared';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {useNavigation} from '@react-navigation/native';
import {StorageKey, storageService} from '../../services/async-storage.service';
export const LoadingScreen = () => {
const getLanguage = async () => {
const response = await AsyncStorage.getItem(StorageKey.Language);
return response;
};
const getOnboardEnd = async () => {
const response = await AsyncStorage.getItem(StorageKey.OnBoarding);
return response;
};
const init = async () => {
let language = await getLanguage();
const isOnBoard = await getOnboardEnd();
if (isOnBoard && language) {
navigate.navigate(RouteKey.Game as any);
} else if (language && !isOnBoard) {
navigate.navigate(RouteKey.Onboarding as any);
} else if (!language) {
navigate.navigate(RouteKey.LanguageSelect as any);
}
};
const navigate = useNavigation();
useEffect(() => {
init();
}, []);
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
backgroundStatusBar={colors.primaryColor}
paddingHorizontal={20}>
<View style={styles.container}>
<ActivityIndicator size="large" />
</View>
</ScreenLayout>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
});

5
src/module/root/screens/on-boarding.screen.tsx

@ -35,9 +35,10 @@ export const Onboarding: FC<IProps> = ({navigation}) => { @@ -35,9 +35,10 @@ export const Onboarding: FC<IProps> = ({navigation}) => {
onPressLeft={() => goBack()}
rightIcon="setting"
onPressRight={() =>
navigation.navigate(RouteKey.Setting, {
{console.log('Option');
navigation.navigate(RouteKey.Setting, {
previous_screen: RouteKey.Onboarding,
})
})}
}
/>
}>

100
src/module/root/screens/questions.tsx

@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
import {
StyleSheet,
Text,
TouchableOpacity,
View,
Image,
Modal,
} from 'react-native';
import {
colors,
Header,
RouteKey,
ScreenLayout,
IRouteParams,
PrimaryBtn,
} from '../../shared';
import React, { useState } from 'react';
import {NameTitle} from '../../shared/components/nameTitle/name-title';
import {RedButton} from '../../shared/components/buttons/red-button';
import circleArrows from '../../../assets/image/circleArrows.svg';
import {QuestionBlock} from '../../shared/components/questionBlock/question-block';
import { MainModal } from '../../shared/components/modals/main-modal';
interface IProps extends IRouteParams {}
export const Questions: React.FC<IProps> = ({navigation}) => {
const [isVisible, setIsVisible] = useState(false);
const goBack = () => {
navigation.navigate(RouteKey.Game);
};
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
backgroundStatusBar={colors.primaryColor}
paddingHorizontal={24}>
<View
style={{
display: 'flex',
flexDirection: 'column',
flex: 1,
justifyContent: 'space-between',
}}>
<View>
<Header
leftIcon="arrow"
gamer={true}
onPressLeft={() => goBack()}
title="Crazy"
/>
<NameTitle name="Player" />
<QuestionBlock />
<MainModal isVisible={isVisible} rate={true}/>
</View>
<View style={styles.buttons}>
<PrimaryBtn
onPress={async () => {}}
children={
<Image
source={require('../../../assets/image/circleArrows.png')}
style={{width: 20, height: 20}}
/>
}
width={101}
/>
<PrimaryBtn
onPress={() => {setIsVisible(true)}}
children={
<Image
source={require('../../../assets/image/play.png')}
style={{width: 20, height: 20}}
/>
}
width={101}
/>
<PrimaryBtn
onPress={async () => {}}
children={
<Image
source={require('../../../assets/image/addPlus.png')}
style={{width: 20, height: 20}}
/>
}
width={101}
/>
</View>
</View>
</ScreenLayout>
);
};
const styles = StyleSheet.create({
buttons: {
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 66,
},
});

46
src/module/services/async-storage.service.ts

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
export enum StorageKey {OnBoarding = 'ONBOARDING_END', Language = 'LANG_SELECTED'};
export class StorageService {
private _local: Partial<Record<StorageKey, any>> = {};
constructor() {
this.init();
}
private init() {
// this.get("TOKEN");
}
private async getFromAsync(key: any) {
const encode = await AsyncStorage.getItem(key);
if (encode) return JSON.parse(encode);
else return null;
}
private async setToAsync(key: any, data: any) {
const encode = JSON.stringify(data);
await AsyncStorage.setItem(key, encode);
}
public async get(key: StorageKey) {
if (this._local[key]) return this._local[key];
return await this.getFromAsync(key);
}
public getLocal(key: StorageKey) {
return this._local[key];
}
public setLocal(key: StorageKey, data: any) {
this._local[key] = data;
}
public async set(key: StorageKey, data: any) {
await this.setToAsync(key, data);
this._local[key] = data;
}
}
export const storageService = new StorageService();

4
src/module/shared/colors/colors.ts

@ -4,4 +4,8 @@ export const colors = { @@ -4,4 +4,8 @@ export const colors = {
prymaryText: '#FFFF',
secondaryText: '#7669C2',
prymaryBtn: '#E36588',
darkPurple: '#2C205C',
purple: '#A798FF',
darkPurple2: '#51418D',
white: '#FFFFFF',
};

10
src/module/shared/components/buttons/primary-btn.component.tsx

@ -4,7 +4,8 @@ import {colors} from '../../colors/colors'; @@ -4,7 +4,8 @@ import {colors} from '../../colors/colors';
interface IProps {
onPress: () => void;
width?: number;
width?: number | string;
color?: string;
children: JSX.Element;
}
export const PrimaryBtn: FC<IProps> = ({
@ -12,11 +13,16 @@ export const PrimaryBtn: FC<IProps> = ({ @@ -12,11 +13,16 @@ export const PrimaryBtn: FC<IProps> = ({
width,
children,
color,
}) => {
return (
<TouchableOpacity
onPress={onPress}
style={[styles.cotainer, {width: width}]}>
style={
!color
? [styles.cotainer, {width: width}]
: [styles.cotainer, {width: width, backgroundColor: color}]
}>
{children}
</TouchableOpacity>
);

32
src/module/shared/components/buttons/red-button.tsx

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
import React from 'react';
import {StyleSheet, TouchableOpacity, Text} from 'react-native';
import { colors } from '../../colors';
interface IProps {
name: string;
}
export const RedButton: React.FC<IProps> = ({name}) => {
return (
<TouchableOpacity style={styles.container}>
<Text style={styles.title}>{name}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
borderRadius: 40,
borderWidth: 1,
borderColor: colors.darkPurple,
height: 66,
width: 188,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 36,
color: '#E36588',
fontWeight: '800'
}
});

22
src/module/shared/components/header/header.component.tsx

@ -9,27 +9,37 @@ interface IProps { @@ -9,27 +9,37 @@ interface IProps {
onPressRight?: () => any;
leftIcon?: string;
rightIcon?: string;
gamer?: boolean;
}
export const Header: FC<IProps> = ({
onPressLeft,
leftIcon,
rightIcon,
title,
gamer,
onPressRight,
}) => {
return (
<View style={styles.header}>
<View style={gamer ? [styles.header, {marginBottom: 16}] : styles.header}>
{leftIcon && (
<TouchableOpacity style={styles.button} onPress={onPressLeft}>
<Icon name={leftIcon} size={22} color={colors.secondaryColor} />
</TouchableOpacity>
)}
<Text style={styles.title}>{title}</Text>
{gamer ? (
<View style={styles.gamerTitle}>
<Text style={styles.title}>{title}</Text>
</View>
) : (
<Text style={styles.title}>{title}</Text>
)}
{rightIcon && (
<TouchableOpacity style={styles.button} onPress={onPressRight}>
<Icon name={rightIcon} size={22} color={colors.secondaryColor} />
</TouchableOpacity>
)}
{gamer && <View style={{width: 27}}></View>}
</View>
);
};
@ -48,6 +58,14 @@ const styles = StyleSheet.create({ @@ -48,6 +58,14 @@ const styles = StyleSheet.create({
color: '#99EDCC',
fontWeight: 'bold',
},
gamerTitle: {
backgroundColor: '#2C205C',
borderRadius: 60,
width: 122,
height: 54,
justifyContent: 'center',
alignItems: 'center',
},
button: {
flex: 0,
width: 22,

124
src/module/shared/components/modals/main-modal.tsx

@ -0,0 +1,124 @@ @@ -0,0 +1,124 @@
import {Modal, View, Text, StyleSheet} from 'react-native';
import React from 'react';
import {colors} from '../../colors';
import {PrimaryBtn} from '../buttons';
interface IProps {
isVisible: boolean;
limit?: boolean;
custom?: boolean;
rate?: boolean;
}
export const MainModal: React.FC<IProps> = ({
isVisible,
limit,
custom,
rate,
}) => {
return (
<Modal visible={isVisible} transparent={true} animationType={'fade'}>
<View style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>
{limit && 'Limit exhausted'} {custom && 'Custom pack'}{' '}
{rate && 'Did you know, that...'}
</Text>
<Text style={styles.description}>
{limit &&
'You have reached the limit of questions for this set. You need the full version to continue, but you can always use “Under18”, “Light”, “Spark” packages. They are always open for you.'}
{custom && 'Add this question to Custom pack?'}
{rate &&
'For an app developer, there is nothing better than 5 🌟 and a positive review'}
</Text>
{!rate ? (
<View style={styles.buttons}>
<PrimaryBtn
onPress={async () => {}}
children={
<Text style={styles.buttonText}>
{limit && 'Cancel'} {custom && 'Yes'}
</Text>
}
width={134}
color={colors.darkPurple}
/>
<PrimaryBtn
onPress={async () => {}}
children={
<Text style={styles.buttonText}>
{limit && 'Buy'} {custom && 'No'}
</Text>
}
width={134}
color={custom ? colors.darkPurple : ''}
/>
</View>
) : (
<View style={styles.buttonsVertical}>
<PrimaryBtn
onPress={async () => {}}
children={<Text style={styles.buttonText}>Rate the app</Text>}
width={'100%'}
/>
<PrimaryBtn
onPress={async () => {}}
children={
<Text style={[styles.buttonText, {fontWeight: '400'}]}>
Let the developer be sad further :(
</Text>
}
width={'100%'}
color={'rgba(0,0,0,0)'}
/>
</View>
)}
</View>
</View>
</Modal>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(44, 32, 92, 0.5)',
},
content: {
width: '93%',
backgroundColor: colors.darkPurple2,
paddingHorizontal: 24,
paddingVertical: 32,
borderRadius: 16,
},
title: {
fontSize: 24,
fontWeight: '700',
color: colors.secondaryColor,
textAlign: 'center',
},
description: {
marginTop: 8,
textAlign: 'center',
fontWeight: '400',
color: colors.white,
fontSize: 18,
lineHeight: 28,
},
buttons: {
marginTop: 34,
justifyContent: 'space-between',
flexDirection: 'row',
},
buttonText: {
fontWeight: '700',
fontSize: 16,
color: colors.white,
},
buttonsVertical: {
marginTop: 34,
justifyContent: 'space-between',
},
});

25
src/module/shared/components/nameTitle/name-title.tsx

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
import {StyleSheet, Text, View} from 'react-native';
import React from 'react';
interface IProps {
name: string;
}
export const NameTitle: React.FC<IProps> = ({name}) => {
return (
<View style={styles.container}>
<Text style={styles.title}>{name}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
},
title: {
color: 'white',
fontSize: 24,
fontWeight: '700',
}
})

37
src/module/shared/components/questionBlock/question-block.tsx

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
import { StyleSheet, View, Text, Image } from "react-native";
import { colors } from "../../colors";
import React from "react";
export const QuestionBlock = () => {
return (
<View style={styles.container}>
<View style={styles.starContainer}>
<Image source={require('../../../../assets/image/magic-star.png')}/>
</View>
<Text style={styles.text}>
Eligendi atque nesciunt natus dolores quis ullam vel temporibus, odit maxime aliquam neque voluptate numquam itaque quam ipsa fugit earum accusamus praesentium!
</Text>
</View>
)
};
const styles = StyleSheet.create({
container: {
marginTop: 88,
width: '100%',
paddingHorizontal: 16,
paddingVertical: 40,
backgroundColor: colors.darkPurple,
borderRadius: 20,
},
starContainer: {
alignItems: 'center',
marginBottom: 14,
},
text: {
color: colors.purple,
fontSize: 22,
fontWeight: '400',
textAlign: 'center',
}
})

3
src/module/shared/enums/route-keys.ts

@ -3,4 +3,7 @@ export enum RouteKey { @@ -3,4 +3,7 @@ export enum RouteKey {
LanguageSelect = 'LanguageSelect',
Setting = 'Setting',
Game = 'Game',
Loading = 'Loading',
Package = 'Package',
Questions = 'Questions',
}

Loading…
Cancel
Save