Browse Source

Add game functionality

pull/1/head
Vadym Tanasiienko 2 years ago committed by Coder
parent
commit
75b66f4628
  1. 8
      App.tsx
  2. 244
      package-lock.json
  3. 5
      package.json
  4. 22
      src/module/package/components/packages-item.component.tsx
  5. 52
      src/module/root/screens/game.tsx
  6. 31
      src/module/root/screens/questions.tsx
  7. 30
      src/module/services/current-step/current-step-slice.tsx
  8. 54
      src/module/services/dares/dares-slice.ts
  9. 6
      src/module/services/shuffle/shuffle.ts
  10. 53
      src/module/services/truths/truth-slice.ts
  11. 11
      src/module/shared/components/buttons/red-button.tsx
  12. 103
      src/module/shared/components/questionBlock/question-block.tsx
  13. 4
      src/module/shared/interfaces/dare.ts
  14. 4
      src/module/shared/interfaces/truth.ts
  15. 5
      src/store/hooks.ts
  16. 15
      src/store/store.ts

8
App.tsx

@ -2,10 +2,16 @@ import React, {useEffect} from 'react'; @@ -2,10 +2,16 @@ import React, {useEffect} from 'react';
import SplashScreen from 'react-native-splash-screen';
import {Navigation} from './src/module/root';
import './src/i18n/index';
import {Provider} from 'react-redux';
import { store } from './src/store/store';
const App = () => {
useEffect(() => {
SplashScreen.hide();
}, []);
return <Navigation />;
return (
<Provider store={store}>
<Navigation />
</Provider>
);
};
export default App;

244
package-lock.json generated

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
"@react-native-async-storage/async-storage": "^1.17.11",
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"@reduxjs/toolkit": "^1.9.2",
"i18next": "^21.8.14",
"i18next-react-native-async-storage": "^1.0.4",
"link": "^1.5.1",
@ -25,7 +26,8 @@ @@ -25,7 +26,8 @@
"react-native-splash-screen": "^3.3.0",
"react-native-svg": "^12.4.4",
"react-native-svg-transformer": "^1.0.0",
"react-native-vector-icons": "^9.2.0"
"react-native-vector-icons": "^9.2.0",
"react-redux": "^8.0.5"
},
"devDependencies": {
"@babel/core": "^7.12.9",
@ -35,6 +37,7 @@ @@ -35,6 +37,7 @@
"@types/jest": "^26.0.23",
"@types/react-native": "^0.66.15",
"@types/react-native-vector-icons": "^6.4.12",
"@types/react-redux": "^7.1.25",
"@types/react-test-renderer": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
@ -3790,6 +3793,29 @@ @@ -3790,6 +3793,29 @@
"nanoid": "^3.1.23"
}
},
"node_modules/@reduxjs/toolkit": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
"integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
"dependencies": {
"immer": "^9.0.16",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || ^18",
"react-redux": "^7.2.1 || ^8.0.2"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-redux": {
"optional": true
}
}
},
"node_modules/@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
@ -4174,6 +4200,15 @@ @@ -4174,6 +4200,15 @@
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -4236,14 +4271,12 @@ @@ -4236,14 +4271,12 @@
"node_modules/@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"node_modules/@types/react": {
"version": "18.0.15",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.15.tgz",
"integrity": "sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -4269,6 +4302,18 @@ @@ -4269,6 +4302,18 @@
"@types/react-native": "*"
}
},
"node_modules/@types/react-redux": {
"version": "7.1.25",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz",
"integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==",
"dev": true,
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"node_modules/@types/react-test-renderer": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
@ -4292,8 +4337,7 @@ @@ -4292,8 +4337,7 @@
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"node_modules/@types/stack-utils": {
"version": "2.0.1",
@ -4301,6 +4345,11 @@ @@ -4301,6 +4345,11 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
"node_modules/@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"node_modules/@types/yargs": {
"version": "15.0.14",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
@ -6212,8 +6261,7 @@ @@ -6212,8 +6261,7 @@
"node_modules/csstype": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
"integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==",
"dev": true
"integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
},
"node_modules/dashdash": {
"version": "1.14.1",
@ -8475,6 +8523,15 @@ @@ -8475,6 +8523,15 @@
"node": ">=4.0"
}
},
"node_modules/immer": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -13553,6 +13610,49 @@ @@ -13553,6 +13610,49 @@
"async-limiter": "~1.0.0"
}
},
"node_modules/react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
"integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"peerDependencies": {
"@types/react": "^16.8 || ^17.0 || ^18.0",
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0",
"react-native": ">=0.59",
"redux": "^4"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/react-refresh": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@ -13672,6 +13772,22 @@ @@ -13672,6 +13772,22 @@
"node": ">= 4"
}
},
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -13894,6 +14010,11 @@ @@ -13894,6 +14010,11 @@
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"node_modules/reselect": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
},
"node_modules/resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@ -16041,7 +16162,7 @@ @@ -16041,7 +16162,7 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/use-subscription/node_modules/use-sync-external-store": {
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
@ -19145,6 +19266,17 @@ @@ -19145,6 +19266,17 @@
"nanoid": "^3.1.23"
}
},
"@reduxjs/toolkit": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
"integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
"requires": {
"immer": "^9.0.16",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7"
}
},
"@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
@ -19395,6 +19527,15 @@ @@ -19395,6 +19527,15 @@
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/istanbul-lib-coverage": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -19457,14 +19598,12 @@ @@ -19457,14 +19598,12 @@
"@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"@types/react": {
"version": "18.0.15",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.15.tgz",
"integrity": "sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -19490,6 +19629,18 @@ @@ -19490,6 +19629,18 @@
"@types/react-native": "*"
}
},
"@types/react-redux": {
"version": "7.1.25",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz",
"integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==",
"dev": true,
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"@types/react-test-renderer": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
@ -19515,8 +19666,7 @@ @@ -19515,8 +19666,7 @@
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"@types/stack-utils": {
"version": "2.0.1",
@ -19524,6 +19674,11 @@ @@ -19524,6 +19674,11 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
"@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"@types/yargs": {
"version": "15.0.14",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
@ -20949,8 +21104,7 @@ @@ -20949,8 +21104,7 @@
"csstype": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
"integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==",
"dev": true
"integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
},
"dashdash": {
"version": "1.14.1",
@ -22651,6 +22805,11 @@ @@ -22651,6 +22805,11 @@
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
"integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA=="
},
"immer": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ=="
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -26509,6 +26668,26 @@ @@ -26509,6 +26668,26 @@
}
}
},
"react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
"integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
"requires": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"dependencies": {
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}
}
},
"react-refresh": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@ -26605,6 +26784,20 @@ @@ -26605,6 +26784,20 @@
"tslib": "^2.0.1"
}
},
"redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"requires": {}
},
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -26778,6 +26971,11 @@ @@ -26778,6 +26971,11 @@
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"reselect": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
},
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@ -28442,16 +28640,14 @@ @@ -28442,16 +28640,14 @@
"integrity": "sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ==",
"requires": {
"use-sync-external-store": "^1.2.0"
},
"dependencies": {
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"requires": {}
}
}
},
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"requires": {}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

5
package.json

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
"@react-native-async-storage/async-storage": "^1.17.11",
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"@reduxjs/toolkit": "^1.9.2",
"i18next": "^21.8.14",
"i18next-react-native-async-storage": "^1.0.4",
"link": "^1.5.1",
@ -32,7 +33,8 @@ @@ -32,7 +33,8 @@
"react-native-splash-screen": "^3.3.0",
"react-native-svg": "^12.4.4",
"react-native-svg-transformer": "^1.0.0",
"react-native-vector-icons": "^9.2.0"
"react-native-vector-icons": "^9.2.0",
"react-redux": "^8.0.5"
},
"devDependencies": {
"@babel/core": "^7.12.9",
@ -42,6 +44,7 @@ @@ -42,6 +44,7 @@
"@types/jest": "^26.0.23",
"@types/react-native": "^0.66.15",
"@types/react-native-vector-icons": "^6.4.12",
"@types/react-redux": "^7.1.25",
"@types/react-test-renderer": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",

22
src/module/package/components/packages-item.component.tsx

@ -1,6 +1,11 @@ @@ -1,6 +1,11 @@
import {useNavigation} from '@react-navigation/native';
import React, {FC} from 'react';
import {StyleSheet, TouchableOpacity, View, Text} from 'react-native';
import {Icon} from '../../shared';
import { useAppDispatch } from '../../../store/hooks';
import { nextStep, resetSteps } from '../../services/current-step/current-step-slice';
import { shuffleDares } from '../../services/dares/dares-slice';
import { shuffleTruths } from '../../services/truths/truth-slice';
import {Icon, RouteKey} from '../../shared';
interface IType {
[key: string]: string;
@ -12,6 +17,7 @@ interface IPackage { @@ -12,6 +17,7 @@ interface IPackage {
questions: IType[];
actions: IType[];
}
export const PackagesItem: FC<IPackage> = ({
title,
description,
@ -19,6 +25,16 @@ export const PackagesItem: FC<IPackage> = ({ @@ -19,6 +25,16 @@ export const PackagesItem: FC<IPackage> = ({
questions,
actions,
}) => {
const navigation = useNavigation();
const dispatch = useAppDispatch();
const play = () => {
navigation.navigate(RouteKey.Package as any);
dispatch(resetSteps());
dispatch(shuffleTruths());
dispatch(shuffleDares());
}
return (
<View style={style.container}>
<View style={style.flex}>
@ -28,7 +44,9 @@ export const PackagesItem: FC<IPackage> = ({ @@ -28,7 +44,9 @@ export const PackagesItem: FC<IPackage> = ({
<Text style={style.description}>{description}</Text>
</View>
</View>
<TouchableOpacity style={style.play} onPress={() => console.log('hello')}>
<TouchableOpacity
style={style.play}
onPress={play}>
<Icon name="play" size={20} color="white" />
</TouchableOpacity>
</View>

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

@ -11,11 +11,17 @@ import {NameTitle} from '../../shared/components/nameTitle/name-title'; @@ -11,11 +11,17 @@ 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}) => {
export const Game: React.FC<IProps> = ({navigation, route}) => {
const goBack = () => {
navigation.navigate(RouteKey.Game);
};
const randomGame = () => {
const isQuestions = Math.random() < 0.5;
navigation.navigate(RouteKey.Questions, {isQuestions})
}
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
@ -30,13 +36,21 @@ export const Game: React.FC<IProps> = ({navigation}) => { @@ -30,13 +36,21 @@ export const Game: React.FC<IProps> = ({navigation}) => {
/>
<NameTitle name="Player" />
<View style={styles.buttons}>
<RedButton name="-TRUTH-" />
<TouchableOpacity>
<Text style={styles.random}>
RANDOM CHANCE
</Text>
<RedButton
name="-TRUTH-"
isQuestions={true}
navigation={navigation}
route={route}
/>
<TouchableOpacity onPress={randomGame}>
<Text style={styles.random}>RANDOM CHANCE</Text>
</TouchableOpacity>
<RedButton name="-DARE-" />
<RedButton
name="-DARE-"
isQuestions={false}
navigation={navigation}
route={route}
/>
</View>
</>
</ScreenLayout>
@ -44,16 +58,16 @@ export const Game: React.FC<IProps> = ({navigation}) => { @@ -44,16 +58,16 @@ export const Game: React.FC<IProps> = ({navigation}) => {
};
const styles = StyleSheet.create({
buttons: {
alignItems: 'center',
height: 240,
justifyContent: 'space-between',
marginTop: 122
},
buttons: {
alignItems: 'center',
height: 240,
justifyContent: 'space-between',
marginTop: 122,
},
random: {
color: '#ffffff',
fontWeight: '400',
fontSize: 18,
}
});
random: {
color: '#ffffff',
fontWeight: '400',
fontSize: 18,
},
});

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

@ -16,19 +16,36 @@ import { @@ -16,19 +16,36 @@ import {
} 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';
import { useAppDispatch } from '../../../store/hooks';
import { nextStep, resetSteps } from '../../services/current-step/current-step-slice';
import { shuffleTruths } from '../../services/truths/truth-slice';
import { shuffleDares } from '../../services/dares/dares-slice';
interface IProps extends IRouteParams {}
export const Questions: React.FC<IProps> = ({navigation}) => {
export const Questions: React.FC<IProps> = ({navigation, route}) => {
const [isVisible, setIsVisible] = useState(false);
const dispatch = useAppDispatch();
console.log(route.params);
const goBack = () => {
navigation.navigate(RouteKey.Game);
};
const goGameScreen = () => {
navigation.navigate(RouteKey.Package);
dispatch(nextStep());
}
const refreshList = () => {
dispatch(shuffleTruths());
dispatch(shuffleDares());
dispatch(resetSteps());
}
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
@ -49,13 +66,13 @@ export const Questions: React.FC<IProps> = ({navigation}) => { @@ -49,13 +66,13 @@ export const Questions: React.FC<IProps> = ({navigation}) => {
title="Crazy"
/>
<NameTitle name="Player" />
<QuestionBlock />
<QuestionBlock isQuestions={route.params.isQuestions}/>
<MainModal isVisible={isVisible} rate={true}/>
</View>
<View style={styles.buttons}>
<PrimaryBtn
onPress={async () => {}}
onPress={refreshList}
children={
<Image
source={require('../../../assets/image/circleArrows.png')}
@ -65,7 +82,7 @@ export const Questions: React.FC<IProps> = ({navigation}) => { @@ -65,7 +82,7 @@ export const Questions: React.FC<IProps> = ({navigation}) => {
width={101}
/>
<PrimaryBtn
onPress={() => {setIsVisible(true)}}
onPress={() => {goGameScreen()}}
children={
<Image
source={require('../../../assets/image/play.png')}
@ -75,7 +92,7 @@ export const Questions: React.FC<IProps> = ({navigation}) => { @@ -75,7 +92,7 @@ export const Questions: React.FC<IProps> = ({navigation}) => {
width={101}
/>
<PrimaryBtn
onPress={async () => {}}
onPress={() => {setIsVisible(true)}}
children={
<Image
source={require('../../../assets/image/addPlus.png')}

30
src/module/services/current-step/current-step-slice.tsx

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../../../store/store";
interface CurrentStepState {
step: number;
}
const initialState: CurrentStepState = {
step: 0,
};
export const CurrentStepSlice = createSlice({
name: "currentStep",
initialState,
reducers: {
nextStep: (state) => {
state.step = state.step + 1;
},
resetSteps: (state) => {
state.step = 0;
},
},
});
export const { nextStep, resetSteps } = CurrentStepSlice.actions;
export const getStep = (state: RootState) => state.currentStep.step;
export default CurrentStepSlice.reducer;

54
src/module/services/dares/dares-slice.ts

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
import {createSlice, PayloadAction} from '@reduxjs/toolkit';
import {RootState} from '../../../store/store';
import { Dare } from '../../shared/interfaces/dare';
import {Truth} from '../../shared/interfaces/truth';
import {shuffle} from '../shuffle/shuffle';
interface DaresState {
dares: Dare[];
shaffledDares: Dare[];
}
const initialState: DaresState = {
dares: [
{
id: 0,
dare: 'Дія 1',
},
{
id: 1,
dare: 'Дія 2',
},
{
id: 2,
dare: 'Дія 3',
},
{
id: 3,
dare: 'Дія 4',
},
{
id: 4,
dare: 'Дія 5',
},
],
shaffledDares: [],
};
export const DaresSlice = createSlice({
name: 'dares',
initialState,
reducers: {
shuffleDares: state => {
state.shaffledDares = shuffle(state.dares);
},
},
});
export const {shuffleDares} = DaresSlice.actions;
export const getDares = (state: RootState) => state.dares.dares;
export const getShuffledDares = (state: RootState) => state.dares.shaffledDares;
export default DaresSlice.reducer;

6
src/module/services/shuffle/shuffle.ts

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
export function shuffle(unshuffled: any[]) {
return unshuffled
.map(value => ({value, sort: Math.random()}))
.sort((a, b) => a.sort - b.sort)
.map(({value}) => value);
}

53
src/module/services/truths/truth-slice.ts

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
import {createSlice, PayloadAction} from '@reduxjs/toolkit';
import {RootState} from '../../../store/store';
import {Truth} from '../../shared/interfaces/truth';
import {shuffle} from '../shuffle/shuffle';
interface TruthsState {
truths: Truth[];
shaffledTruth: Truth[];
}
const initialState: TruthsState = {
truths: [
{
id: 0,
question: 'Питання 1',
},
{
id: 1,
question: 'Питання 2',
},
{
id: 2,
question: 'Питання 3',
},
{
id: 3,
question: 'Питання 4',
},
{
id: 4,
question: 'Питання 5',
},
],
shaffledTruth: [],
};
export const TruthSlice = createSlice({
name: 'truth',
initialState,
reducers: {
shuffleTruths: state => {
state.shaffledTruth = shuffle(state.truths);
},
},
});
export const {shuffleTruths} = TruthSlice.actions;
export const getTruths = (state: RootState) => state.truth.truths;
export const getShuffledTruths = (state: RootState) => state.truth.shaffledTruth;
export default TruthSlice.reducer;

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

@ -1,14 +1,19 @@ @@ -1,14 +1,19 @@
import { useNavigation } from '@react-navigation/native';
import React from 'react';
import {StyleSheet, TouchableOpacity, Text} from 'react-native';
import { colors } from '../../colors';
import { RouteKey } from '../../enums';
import { IRouteParams } from '../../interfaces';
interface IProps {
interface IProps extends IRouteParams {
name: string;
isQuestions: boolean;
}
export const RedButton: React.FC<IProps> = ({name}) => {
export const RedButton: React.FC<IProps> = ({name , isQuestions, navigation}) => {
return (
<TouchableOpacity style={styles.container}>
<TouchableOpacity style={styles.container} onPress={() => navigation.navigate(RouteKey.Questions, {isQuestions})}>
<Text style={styles.title}>{name}</Text>
</TouchableOpacity>
);

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

@ -1,37 +1,78 @@ @@ -1,37 +1,78 @@
import { StyleSheet, View, Text, Image } from "react-native";
import { colors } from "../../colors";
import React from "react";
import {StyleSheet, View, Text, Image} from 'react-native';
import {colors} from '../../colors';
import React, {useEffect, useState} from 'react';
import {useNavigation} from '@react-navigation/native';
import {RouteKey} from '../../enums';
import {useAppDispatch, useAppSelector} from '../../../../store/hooks';
import {
getStep,
resetSteps,
} from '../../../services/current-step/current-step-slice';
import {
getShuffledTruths,
shuffleTruths,
} from '../../../services/truths/truth-slice';
import {getShuffledDares, shuffleDares} from '../../../services/dares/dares-slice';
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>
)
interface IProps {
isQuestions: boolean;
}
export const QuestionBlock: React.FC<IProps> = ({isQuestions}) => {
const navigation = useNavigation();
const dispatch = useAppDispatch();
const currentStep = useAppSelector(getStep);
const shuffledTruths = useAppSelector(getShuffledTruths);
const shuffledDares = useAppSelector(getShuffledDares);
console.log(currentStep);
useEffect(() => {
if (currentStep >= shuffledTruths.length) {
dispatch(resetSteps());
dispatch(shuffleTruths());
}
if (currentStep >= shuffledDares.length) {
dispatch(resetSteps());
dispatch(shuffleDares());
}
}, [currentStep]);
return (
<View style={styles.container}>
<View style={styles.starContainer}>
<Image source={require('../../../../assets/image/magic-star.png')} />
</View>
<Text style={styles.text}>
{currentStep < shuffledTruths.length &&
isQuestions &&
shuffledTruths[currentStep].question}
{currentStep < shuffledDares.length &&
!isQuestions &&
shuffledDares[currentStep].dare}
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
marginTop: 88,
width: '100%',
paddingHorizontal: 16,
paddingVertical: 40,
backgroundColor: colors.darkPurple,
borderRadius: 20,
},
starContainer: {
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',
}
})
},
text: {
color: colors.purple,
fontSize: 22,
fontWeight: '400',
textAlign: 'center',
},
});

4
src/module/shared/interfaces/dare.ts

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
export interface Dare {
id: number;
dare: string;
}

4
src/module/shared/interfaces/truth.ts

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
export interface Truth {
id: number;
question: string;
}

5
src/store/hooks.ts

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from './store';
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

15
src/store/store.ts

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
import { configureStore } from '@reduxjs/toolkit';
import currentStepSlice from '../module/services/current-step/current-step-slice';
import daresSlice from '../module/services/dares/dares-slice';
import truthsSlice from '../module/services/truths/truth-slice';
export const store = configureStore({
reducer: {
currentStep: currentStepSlice,
truth: truthsSlice,
dares: daresSlice,
},
});
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
Loading…
Cancel
Save