From 9c7dfe4459dbd655181ceeb6a8efe5878013eb05 Mon Sep 17 00:00:00 2001 From: Vlad Narizhnyi Date: Thu, 11 Jan 2024 09:58:15 +0000 Subject: [PATCH 1/3] FIX | Fix sort bug (#6) Co-authored-by: Vlad Reviewed-on: https://gitlab.work-jetup.site/Vitalik/truthordare/pulls/6 Co-authored-by: Vlad Narizhnyi Co-committed-by: Vlad Narizhnyi --- .../questions-dares-list.ts | 36 +++++++-------- .../common/typing/enums/storage-key.enum.ts | 1 + .../hooks/get-current-truth-dares.hook.tsx | 46 +++++++++++++------ .../game/hooks/use-set-steps-by-package.tsx | 2 - .../packages/config/packages-list.config.tsx | 2 +- src/store/slices/custom-package.slice.ts | 10 +--- src/store/slices/game-items.slice.ts | 29 ++++++++++-- 7 files changed, 77 insertions(+), 49 deletions(-) diff --git a/src/module/common/questions-dares-list/questions-dares-list.ts b/src/module/common/questions-dares-list/questions-dares-list.ts index 932d64a..2d33ea3 100644 --- a/src/module/common/questions-dares-list/questions-dares-list.ts +++ b/src/module/common/questions-dares-list/questions-dares-list.ts @@ -257,8 +257,8 @@ export const light = [ { id: 2, isDare: true, - en: 'Одягни на вуха носки і сиди так 3 раунда.', - ua: 'Put socks on your ears and sit like that for 3 rounds.', + ua: 'Одягни на вуха носки і сиди так 3 раунда.', + en: 'Put socks on your ears and sit like that for 3 rounds.', }, { id: 3, @@ -275,8 +275,8 @@ export const light = [ { id: 5, isDare: false, - en: 'Найекстремальніше, що ти робив(ла), щоб комусь сподобатись?', - ua: "What's the most extreme thing you've done to please someone?", + ua: 'Найекстремальніше, що ти робив(ла), щоб комусь сподобатись?', + en: "What's the most extreme thing you've done to please someone?", }, { id: 6, @@ -288,7 +288,7 @@ export const light = [ id: 7, isDare: false, en: 'If you could be invisible for a day, what would you do?', - ua: 'Якщо б ви могли бути невидимими на один день, Що б ти зробив(ла), якб?', + ua: 'Якщо б ви могли бути невидимими на один день, Що б ти зробив(ла)?', }, { id: 8, @@ -347,8 +347,8 @@ export const light = [ { id: 17, isDare: false, - en: 'What do you often look at on the Internet?', - ua: 'Про що ти часто дивишся в інтернеті?', + en: 'Tell the first impression when you saw the person on the left of you', + ua: 'Розкажи перше враження, коли ти побачив(ла) людину ліворуч віж тебе', }, { id: 18, @@ -371,8 +371,8 @@ export const light = [ { id: 21, isDare: false, - en: 'Tell the funniest story about how you threw up.', - ua: 'Розкажи про якусь ситуацію, яку ти бачив на власні очі.', + en: 'Tell me about some trashy situation that you saw with your own eyes.', + ua: 'Розкажи про якусь трешову ситуацію, яку ти бачив на власні очі.', }, { id: 22, @@ -407,8 +407,8 @@ export const light = [ { id: 27, isDare: false, - en: 'Have you ever followed someone?', - ua: 'Ти колись слідкував за кимось?', + en: 'Have you ever followed someone live?', + ua: 'Ти колись слідкував за кимось вживу?', }, { id: 28, @@ -420,7 +420,7 @@ export const light = [ id: 27, isDare: false, en: 'Tell about the channel that you immediately open when something new appears there.', - ua: 'Розкажи про канал, який ти одразу відкриваєш, коли там з являється щось нове.', + ua: "Розкажи про канал, який ти одразу відкриваєш, коли там з'являється щось нове.", }, { id: 28, @@ -431,8 +431,8 @@ export const light = [ { id: 29, isDare: false, - en: 'Tell about the channel that you immediately open when something new appears there.', - ua: 'Розкажи про канал, який ти одразу відкриваєш, коли там з являється щось нове.', + en: 'What act do you feel ashamed of?', + ua: 'За який вчинок ти відчуваєш сором?', }, { id: 30, @@ -455,8 +455,8 @@ export const light = [ { id: 33, isDare: false, - en: 'Have you ever been dumped by a person you liked?', - ua: 'Тебе колись кидала людина, яка тобі подобалась?', + en: 'What act do you feel proud of?', + ua: 'За який вчинок ти відчуваєш гордість?', }, { id: 34, @@ -572,8 +572,8 @@ export const crazy = [ { id: 12, isDare: false, - en: 'Є людина, яку ти ненавидиш, але вона про це не знає?', - ua: "Is there a person you hate, but they don't know it?", + ua: 'Є людина, яку ти ненавидиш, але вона про це не знає?', + en: "Is there a person you hate, but they don't know it?", }, { id: 13, diff --git a/src/module/common/typing/enums/storage-key.enum.ts b/src/module/common/typing/enums/storage-key.enum.ts index abdb6f8..b4667a7 100644 --- a/src/module/common/typing/enums/storage-key.enum.ts +++ b/src/module/common/typing/enums/storage-key.enum.ts @@ -5,6 +5,7 @@ export enum StorageKey { Products = 'Products', CustomPackage = 'CustomPackage', ShuffleCustomPackage = 'ShuffleCustomPackage', + ShufflePackage = 'ShufflePackage', Players = 'Players', LimitForCrazy = 'limit', SavedSteps = 'SavedSteps', diff --git a/src/module/game/hooks/get-current-truth-dares.hook.tsx b/src/module/game/hooks/get-current-truth-dares.hook.tsx index b6f019d..41623ad 100644 --- a/src/module/game/hooks/get-current-truth-dares.hook.tsx +++ b/src/module/game/hooks/get-current-truth-dares.hook.tsx @@ -19,7 +19,6 @@ import { import { useTranslation } from 'react-i18next' import { useDispatch, useSelector } from 'react-redux' import { RootState } from '~store/store' -import firestore from '@react-native-firebase/firestore' import _ from 'lodash' interface UseTruthOrDareProps { @@ -52,7 +51,7 @@ export const useGetCurrentTruthOrDare = ({ } const getGameItemsByCustomPackage = () => { - if (_.isEmpty(customPackageShuffle.questions)) + if (_.isEmpty(customPackageShuffle[customType])) return customPackage[customType] return customPackageShuffle[customType] @@ -69,18 +68,20 @@ export const useGetCurrentTruthOrDare = ({ const packageTruthsOrDares = getGameItemsByPackage() const currentItem = getCurrentItem() - console.log('currentItem', currentItem) - console.log('customTruthsOrDares', customTruthsOrDares) - const shuffleAndSavePackage = async () => { - const shufflePackages = _.shuffle(packageTruthsOrDares) - await firestore() - .collection('content') - .doc(packageType) - .update(shufflePackages) + const savedShuffle = await storageService.get(StorageKey.ShufflePackage) + + const shuffleItems = _.shuffle(savedShuffle[packageType]) + + const newShuffle = { + ...savedShuffle, + [packageType]: shuffleItems, + } + + await storageService.set(StorageKey.ShufflePackage, newShuffle) dispatch(resetStepsByTruthOrDare(choiceType)) - dispatch(shufflePackage(packageType)) + dispatch(shufflePackage({ packageType, shuffleItems })) } const shuffleAndSaveCustomPackage = async () => { @@ -88,18 +89,33 @@ export const useGetCurrentTruthOrDare = ({ const shuffleCustom = _.shuffle(customTruthsOrDares) - dispatch(shuffleCustomPackage({ customType, shuffleCustom })) - dispatch(resetStepsByTruthOrDare(choiceType)) - const savedShuffleCustom = await storageService.get( StorageKey.ShuffleCustomPackage, ) + if (!savedShuffleCustom?.[customType]) { + const newShuffled = { + ...customPackage, + [customType]: shuffleCustom, + } + + dispatch(shuffleCustomPackage(newShuffled)) + + return await storageService.set( + StorageKey.ShuffleCustomPackage, + newShuffled, + ) + } + const newShuffled = { ...savedShuffleCustom, [customType]: shuffleCustom, } + await storageService.set(StorageKey.ShuffleCustomPackage, newShuffled) + + dispatch(shuffleCustomPackage(newShuffled)) + dispatch(resetStepsByTruthOrDare(choiceType)) } const checkIsNeedShuffle = () => { @@ -120,7 +136,7 @@ export const useGetCurrentTruthOrDare = ({ useEffect(() => { checkIsNeedShuffle() - }, [currentStep]) + }, [currentStep, customTruthsOrDares]) return currentItem } diff --git a/src/module/game/hooks/use-set-steps-by-package.tsx b/src/module/game/hooks/use-set-steps-by-package.tsx index ff83d11..b0b8435 100644 --- a/src/module/game/hooks/use-set-steps-by-package.tsx +++ b/src/module/game/hooks/use-set-steps-by-package.tsx @@ -11,8 +11,6 @@ export const useSetStepsByPackage = (packageType: PackageType) => { const stepsByPackage = lastSteps?.[packageType] - console.log('stepsByPackage', stepsByPackage) - if (!stepsByPackage) return dispatch(resetSteps()) dispatch(setStep(stepsByPackage)) diff --git a/src/module/packages/config/packages-list.config.tsx b/src/module/packages/config/packages-list.config.tsx index 08a1b65..937c3b3 100644 --- a/src/module/packages/config/packages-list.config.tsx +++ b/src/module/packages/config/packages-list.config.tsx @@ -27,7 +27,7 @@ export const packageListConfig = [ /> ), description: { - ua: 'Challenge your friends or your significant other and see how far they can go!', + ua: 'Веселі та несподівані завдання гарантовано розсмішять та відкриють нові факти з життя учасників!', en: 'Fun and unexpected tasks are guaranteed to make you laugh and discover new facts from the life of the participants.', }, }, diff --git a/src/store/slices/custom-package.slice.ts b/src/store/slices/custom-package.slice.ts index da739a9..96bedb9 100644 --- a/src/store/slices/custom-package.slice.ts +++ b/src/store/slices/custom-package.slice.ts @@ -49,15 +49,9 @@ export const customPackageSlice = createSlice({ reducers: { shuffleCustomPackage: ( state, - action: PayloadAction<{ - shuffleCustom: string[] - customType: CustomType - }>, + action: PayloadAction, ) => { - const shuffleItems = action.payload.shuffleCustom - const customType = action.payload.customType - - state.shuffleCustom[customType] = shuffleItems + state.shuffleCustom = action.payload }, addCustomItem: ( state, diff --git a/src/store/slices/game-items.slice.ts b/src/store/slices/game-items.slice.ts index 99c8bf4..1396ff5 100644 --- a/src/store/slices/game-items.slice.ts +++ b/src/store/slices/game-items.slice.ts @@ -1,6 +1,11 @@ import { PayloadAction, createAsyncThunk, createSlice } from '@reduxjs/toolkit' import firestore from '@react-native-firebase/firestore' -import { GameItem, PackageType } from '../../module/common' +import { + GameItem, + PackageType, + StorageKey, + storageService, +} from '../../module/common' import { RootState } from '../store' import _ from 'lodash' @@ -34,7 +39,14 @@ export const getGameItemsFromFirestore = createAsyncThunk( return acc }, {}) - return allPackages + const saved = await storageService.get(StorageKey.ShufflePackage) + + if (!saved) { + await storageService.set(StorageKey.ShufflePackage, allPackages) + return allPackages + } + + return saved }, ) @@ -42,15 +54,22 @@ export const gameItemsSlice = createSlice({ name: 'gameItems', initialState, reducers: { - shufflePackage: (state, action: PayloadAction) => { - const packageType = action.payload - state[packageType] = _.shuffle(state[packageType]) + shufflePackage: ( + state, + action: PayloadAction<{ + packageType: PackageType + shuffleItems: GameItem[] + }>, + ) => { + const packageType = action.payload.packageType + state[packageType] = action.payload.shuffleItems }, }, extraReducers(builder) { builder .addCase(getGameItemsFromFirestore.fulfilled, (state, action) => { const allPackages = action.payload + state.under18 = allPackages[PackageType.Under18] state.light = allPackages[PackageType.Light] state.crazy = allPackages[PackageType.Crazy] From 314afb8ea5169a78759e5e7464715ad3757e439e Mon Sep 17 00:00:00 2001 From: Vlad Narizhnyi Date: Thu, 11 Jan 2024 12:57:22 +0000 Subject: [PATCH 2/3] FIX | Add crazy package for purchase (#7) Co-authored-by: Vlad Reviewed-on: https://gitlab.work-jetup.site/Vitalik/truthordare/pulls/7 Co-authored-by: Vlad Narizhnyi Co-committed-by: Vlad Narizhnyi --- android/app/_BUCK | 4 +- android/app/build.gradle | 2 +- android/app/google-services.json | 92 +++++++++---------- .../java/com/truth/ReactNativeFlipper.java | 2 +- android/app/src/main/AndroidManifest.xml | 2 +- .../MainActivity.java | 2 +- .../MainApplication.java | 2 +- ios/GoogleService-Info.plist | 4 +- ios/Podfile.lock | 2 +- .../common/typing/enums/products.enum.ts | 2 +- .../packages/config/packages-list.config.tsx | 2 +- 11 files changed, 58 insertions(+), 58 deletions(-) rename android/app/src/main/java/com/{truth => truthoraction.jetup}/MainActivity.java (95%) rename android/app/src/main/java/com/{truth => truthoraction.jetup}/MainApplication.java (98%) diff --git a/android/app/_BUCK b/android/app/_BUCK index 2632cfc..a4bb7f4 100644 --- a/android/app/_BUCK +++ b/android/app/_BUCK @@ -35,12 +35,12 @@ android_library( android_build_config( name = "build_config", - package = "com.truth", + package = "com.truthoraction.jetup", ) android_resource( name = "res", - package = "com.truth", + package = "com.truthoraction.jetup", res = "src/main/res", ) diff --git a/android/app/build.gradle b/android/app/build.gradle index 77f70d0..b5ba00b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -29,7 +29,7 @@ android { compileSdkVersion rootProject.ext.compileSdkVersion defaultConfig { - applicationId "com.truth" + applicationId "com.truthoraction.jetup" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 diff --git a/android/app/google-services.json b/android/app/google-services.json index e9f143d..4e9a4b7 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,47 +1,47 @@ { - "project_info": { - "project_number": "552568521005", - "firebase_url": "https://truthordare-6493e-default-rtdb.europe-west1.firebasedatabase.app", - "project_id": "truth-or-dare-fcc54", - "storage_bucket": "truthordare-6493e.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:180425292880:android:8690e5274abb413c7da555", - "android_client_info": { - "package_name": "com.truth" - } - }, - "oauth_client": [ - { - "client_id": "180425292880-1pfj1drhgqc9j19jit1ahfu7jouodjej.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyBXoidUFjbE84RZ8PqIP0IGAsTYU28PEO8" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "180425292880-1pfj1drhgqc9j19jit1ahfu7jouodjej.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "180425292880-bfueoq3p0oq0b0lf2qviebio2q338eu8.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "org.reactjs.native.example.Truth" - } - } - ] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file + "project_info": { + "project_number": "552568521005", + "firebase_url": "https://truthordare-6493e-default-rtdb.europe-west1.firebasedatabase.app", + "project_id": "truth-or-dare-fcc54", + "storage_bucket": "truthordare-6493e.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:180425292880:android:8690e5274abb413c7da555", + "android_client_info": { + "package_name": "com.truthoraction.jetup" + } + }, + "oauth_client": [ + { + "client_id": "180425292880-1pfj1drhgqc9j19jit1ahfu7jouodjej.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBXoidUFjbE84RZ8PqIP0IGAsTYU28PEO8" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "180425292880-1pfj1drhgqc9j19jit1ahfu7jouodjej.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "180425292880-bfueoq3p0oq0b0lf2qviebio2q338eu8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "org.reactjs.native.example.Truth" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} diff --git a/android/app/src/debug/java/com/truth/ReactNativeFlipper.java b/android/app/src/debug/java/com/truth/ReactNativeFlipper.java index 5fce807..38cd734 100644 --- a/android/app/src/debug/java/com/truth/ReactNativeFlipper.java +++ b/android/app/src/debug/java/com/truth/ReactNativeFlipper.java @@ -4,7 +4,7 @@ *

This source code is licensed under the MIT license found in the LICENSE file in the root * directory of this source tree. */ -package com.truth; +package com.truthoraction.jetup; import android.content.Context; import com.facebook.flipper.android.AndroidFlipperClient; diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index ffe2afb..b1ffdcb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.truthoraction.jetup"> diff --git a/android/app/src/main/java/com/truth/MainActivity.java b/android/app/src/main/java/com/truthoraction.jetup/MainActivity.java similarity index 95% rename from android/app/src/main/java/com/truth/MainActivity.java rename to android/app/src/main/java/com/truthoraction.jetup/MainActivity.java index e90f56a..12b1f96 100644 --- a/android/app/src/main/java/com/truth/MainActivity.java +++ b/android/app/src/main/java/com/truthoraction.jetup/MainActivity.java @@ -1,4 +1,4 @@ -package com.truth; +package com.truthoraction.jetup; import android.os.Bundle; import com.facebook.react.ReactActivity; diff --git a/android/app/src/main/java/com/truth/MainApplication.java b/android/app/src/main/java/com/truthoraction.jetup/MainApplication.java similarity index 98% rename from android/app/src/main/java/com/truth/MainApplication.java rename to android/app/src/main/java/com/truthoraction.jetup/MainApplication.java index 8fa5fc6..46d7cf5 100644 --- a/android/app/src/main/java/com/truth/MainApplication.java +++ b/android/app/src/main/java/com/truthoraction.jetup/MainApplication.java @@ -1,4 +1,4 @@ -package com.truth; +package com.truthoraction.jetup; import android.app.Application; import com.facebook.react.PackageList; diff --git a/ios/GoogleService-Info.plist b/ios/GoogleService-Info.plist index 6de5eb2..e49debf 100644 --- a/ios/GoogleService-Info.plist +++ b/ios/GoogleService-Info.plist @@ -9,7 +9,7 @@ PLIST_VERSION 1 BUNDLE_ID - com.truth + com.truthoraction.jetup PROJECT_ID truth-or-dare-fcc54 STORAGE_BUCKET @@ -25,6 +25,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:552568521005:ios:66c16d5229fe90142353a4 + 1:552568521005:ios:05030eb25d2be7bf2353a4 \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1ccbafb..30d2d7b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1590,4 +1590,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 0c63220a19ca9fd3d2ce02dc5eecdb8c820bf5ab -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.1 diff --git a/src/module/common/typing/enums/products.enum.ts b/src/module/common/typing/enums/products.enum.ts index 5254ae6..00840dd 100644 --- a/src/module/common/typing/enums/products.enum.ts +++ b/src/module/common/typing/enums/products.enum.ts @@ -1,3 +1,3 @@ export enum ProductsEnum { - Crazy = 'Crz', + Crazy = 'crz', } diff --git a/src/module/packages/config/packages-list.config.tsx b/src/module/packages/config/packages-list.config.tsx index 937c3b3..39e6b14 100644 --- a/src/module/packages/config/packages-list.config.tsx +++ b/src/module/packages/config/packages-list.config.tsx @@ -27,7 +27,7 @@ export const packageListConfig = [ /> ), description: { - ua: 'Веселі та несподівані завдання гарантовано розсмішять та відкриють нові факти з життя учасників!', + ua: 'Веселі та несподівані завдання гарантовано розсмішать та відкриють нові факти з життя учасників!', en: 'Fun and unexpected tasks are guaranteed to make you laugh and discover new facts from the life of the participants.', }, }, From fde610608c3015f9813efa19f79307451aff3266 Mon Sep 17 00:00:00 2001 From: Vlad Narizhnyi Date: Mon, 15 Jan 2024 10:01:44 +0000 Subject: [PATCH 3/3] FEATURE | Add voiceover text & fix bugs (#8) https://jetup-digital.atlassian.net/jira/software/projects/TRUT/boards/90?selectedIssue=TRUT-18 Co-authored-by: Vlad Reviewed-on: https://gitlab.work-jetup.site/Vitalik/truthordare/pulls/8 Co-authored-by: Vlad Narizhnyi Co-committed-by: Vlad Narizhnyi --- .../app/src/main/assets/fonts/fontello.ttf | Bin 17324 -> 17624 bytes ios/GoogleService-Info.plist | 2 + ios/Podfile.lock | 6 + ios/Truth.xcodeproj/project.pbxproj | 4 +- package-lock.json | 11 ++ package.json | 1 + src/assets/resources/fonts/fontello.ttf | Bin 17324 -> 17624 bytes src/config/fontello.json | 6 + src/i18n/interfaces/common.interface.ts | 1 + .../interfaces/settings.types.interface.ts | 1 + src/i18n/locales/en/common.translation.ts | 1 + src/i18n/locales/en/settings.translation.ts | 1 + src/i18n/locales/ua/common.translation.ts | 11 +- .../questions-dares-list.ts | 36 +++--- .../common/typing/enums/storage-key.enum.ts | 1 + .../use-animation-truth-or-dare.hook.ts | 42 ++++++- src/module/game/components/index.ts | 2 +- .../components/player-field.component.tsx | 2 +- .../game/components/truth-or-dare-view.tsx | 53 --------- src/module/game/components/truth-or-dare.tsx | 104 ++++++++++++++++++ src/module/game/config/index.ts | 1 + src/module/game/config/voice.config.ts | 12 ++ .../hooks/get-current-truth-dares.hook.tsx | 12 +- src/module/game/hooks/index.ts | 1 + src/module/game/hooks/use-voice.hook.tsx | 42 +++++++ src/module/game/screens/game.screen.tsx | 4 +- src/module/game/screens/players.screen.tsx | 24 ++-- .../game/screens/truth-or-dare.screen.tsx | 24 ++-- .../animation/use-animation-list.hook.ts | 9 +- .../atoms/packages-page-separator.atom.tsx | 17 ++- .../root/navigations-groups/user.group.tsx | 1 + src/module/root/screens/loading-screen.tsx | 9 ++ src/module/settings/atoms/index.ts | 1 + .../atoms/switch-notifications.atom.tsx | 2 +- .../settings/atoms/switch-voiceover.atom.tsx | 33 ++++++ .../settings/config/settings.config.tsx | 11 +- .../settings/screens/settings.screen.tsx | 2 + src/store/slices/players.slice.ts | 21 +--- 38 files changed, 363 insertions(+), 148 deletions(-) delete mode 100644 src/module/game/components/truth-or-dare-view.tsx create mode 100644 src/module/game/components/truth-or-dare.tsx create mode 100644 src/module/game/config/voice.config.ts create mode 100644 src/module/game/hooks/use-voice.hook.tsx create mode 100644 src/module/settings/atoms/switch-voiceover.atom.tsx diff --git a/android/app/src/main/assets/fonts/fontello.ttf b/android/app/src/main/assets/fonts/fontello.ttf index 96a2c6d2c148587ccac2c3b3f7262f523c2d05cd..612bdbf15d8eb418fb584db89ce81c66f4b51f94 100644 GIT binary patch delta 947 zcmX|9T}V@57=FL=v#l}rbjhA&147`=P=_YUL#w)|{;t&}@28pco9(VME=REK8ywCTY!+XBBkID8jdEs7s z06_WxU^tPD^XuxPF4XS;sO`kevHtd3SbT~{Uys^~tQyPA zjUFYQ{sv&40Msp|Q}Lufd3^++L52Nr8V!|_xq`YKwI`jOo=rZyQ9M8+iAFjzk%+JU zdTvMkN!pN&&+=qb*9#D2P`mELv#G6Dl~t%c_<>ve#MJc8*Dvz`9G*cu{A7w>*l5`R z=!mZT9V9!#0Ga4r1A?0YUIKkw)gh}fz6K18qpt=PP(X!qH@kAjL>fuwRi>sbjUKKIf*jBfVB)L$65v$v6cZ9 zSjzwt);MDcU`EFGO8^V9uLO|#krF7dIotIT31er8nmHUkW-*lu=_fnDvs3#>!2{ zen+TqsFAH2-6-GeO7hKQm@*dj36%6?_4q|!@->orrDYfT0ybeN;H5CP6zF!8eb%n(GWv4El2L7JGwxNanx2{4 zF)Up`d;VMC3?ZEGqhW(^`SsvsLhQoNP>>>(f{R;Fu-SW4w-dr^u2QMwGx539r0||| QDcD3N6`#z1=RRov1M{2HSpWb4 delta 657 zcmYL`PiPZC6vn^VEG8*2o93U{6ly??pr&TCO(`gN&{HldNIfW+HGd0DvY540si}pc zD1wnWst5%^P@%XGPgU@wXg!Dr1r?;1J$NXhpiqc!vWf%W`_1>}z2WWbhimN7Ro30H za2a6702E6N!wjz8tdd^=q<5uRD@A!)<3A__t7ffncI@{>ATN^*)Qq-C`4F9dBl>DH z7pkH1>K;H|0``{c6{Ea6^Zo{~-=Xt~IwgD&xd3ESq8j*|aGKGifDm9@Lc5%QZf;F{TLTOWu0uK@iG4ZYnwS1~)i13lny z=+>`O>@z>XS|^vms2R8e&tSKYI7H>kkRj#|zy}Gkv(+H;m4&-UX;8_U{FBA4_1Po_B>or=q3^b>79hcdpX0dAQ*N9!H6pe zMqNQL;R-RL>I!jU+7-4DCtZPR=?l@n=Xq*(<;A3(Nv(%Q7q5G)Gs?lAP(0#i;OqUD zv;WD*v{BIq`T5`162@IBH#L=C(suEV=H-vIL&;zu_(fR?eGkuvS0Yotruth-or-dare-fcc54.appspot.com IS_ADS_ENABLED + ITSAppUsesNonExemptEncryption + IS_ANALYTICS_ENABLED IS_APPINVITE_ENABLED diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 30d2d7b..2c33042 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1286,6 +1286,8 @@ PODS: - RNVectorIcons (9.2.0): - React-Core - SocketRocket (0.6.1) + - TextToSpeech (4.1.0): + - React - Yoga (1.14.0) - YogaKit (1.18.1): - Yoga (~> 1.14) @@ -1368,6 +1370,7 @@ DEPENDENCIES: - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) + - TextToSpeech (from `../node_modules/react-native-tts`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -1503,6 +1506,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-svg" RNVectorIcons: :path: "../node_modules/react-native-vector-icons" + TextToSpeech: + :path: "../node_modules/react-native-tts" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -1585,6 +1590,7 @@ SPEC CHECKSUMS: RNSVG: d7d7bc8229af3842c9cfc3a723c815a52cdd1105 RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 + TextToSpeech: b3aa777ff5585705f179c0a2436bfd0926d1716e Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/ios/Truth.xcodeproj/project.pbxproj b/ios/Truth.xcodeproj/project.pbxproj index 862d163..5591594 100644 --- a/ios/Truth.xcodeproj/project.pbxproj +++ b/ios/Truth.xcodeproj/project.pbxproj @@ -547,7 +547,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 7LY53JU2YB; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -616,7 +616,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 7LY53JU2YB; HEADER_SEARCH_PATHS = ( "$(inherited)", diff --git a/package-lock.json b/package-lock.json index a9098a2..d60c34d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "react-native-splash-screen": "^3.3.0", "react-native-svg": "^12.5.1", "react-native-svg-transformer": "^1.0.0", + "react-native-tts": "^4.1.0", "react-native-vector-icons": "^9.2.0", "react-redux": "^9.0.4", "validate.js": "^0.13.1" @@ -13517,6 +13518,11 @@ "react-native-svg": ">=12.0.0" } }, + "node_modules/react-native-tts": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/react-native-tts/-/react-native-tts-4.1.0.tgz", + "integrity": "sha512-tvf3lQ6u9MqztUie37qoPw5YQPqi0ql1lPhDsBBs/RRA6A/H1J9X9H/qb1A0Hx0ZpjavrEdtVSqQQ2JDZvZCTQ==" + }, "node_modules/react-native-vector-icons": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz", @@ -25487,6 +25493,11 @@ "path-dirname": "^1.0.2" } }, + "react-native-tts": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/react-native-tts/-/react-native-tts-4.1.0.tgz", + "integrity": "sha512-tvf3lQ6u9MqztUie37qoPw5YQPqi0ql1lPhDsBBs/RRA6A/H1J9X9H/qb1A0Hx0ZpjavrEdtVSqQQ2JDZvZCTQ==" + }, "react-native-vector-icons": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz", diff --git a/package.json b/package.json index 332617f..bbbe1d0 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "react-native-splash-screen": "^3.3.0", "react-native-svg": "^12.5.1", "react-native-svg-transformer": "^1.0.0", + "react-native-tts": "^4.1.0", "react-native-vector-icons": "^9.2.0", "react-redux": "^9.0.4", "validate.js": "^0.13.1" diff --git a/src/assets/resources/fonts/fontello.ttf b/src/assets/resources/fonts/fontello.ttf index 96a2c6d2c148587ccac2c3b3f7262f523c2d05cd..612bdbf15d8eb418fb584db89ce81c66f4b51f94 100644 GIT binary patch delta 947 zcmX|9T}V@57=FL=v#l}rbjhA&147`=P=_YUL#w)|{;t&}@28pco9(VME=REK8ywCTY!+XBBkID8jdEs7s z06_WxU^tPD^XuxPF4XS;sO`kevHtd3SbT~{Uys^~tQyPA zjUFYQ{sv&40Msp|Q}Lufd3^++L52Nr8V!|_xq`YKwI`jOo=rZyQ9M8+iAFjzk%+JU zdTvMkN!pN&&+=qb*9#D2P`mELv#G6Dl~t%c_<>ve#MJc8*Dvz`9G*cu{A7w>*l5`R z=!mZT9V9!#0Ga4r1A?0YUIKkw)gh}fz6K18qpt=PP(X!qH@kAjL>fuwRi>sbjUKKIf*jBfVB)L$65v$v6cZ9 zSjzwt);MDcU`EFGO8^V9uLO|#krF7dIotIT31er8nmHUkW-*lu=_fnDvs3#>!2{ zen+TqsFAH2-6-GeO7hKQm@*dj36%6?_4q|!@->orrDYfT0ybeN;H5CP6zF!8eb%n(GWv4El2L7JGwxNanx2{4 zF)Up`d;VMC3?ZEGqhW(^`SsvsLhQoNP>>>(f{R;Fu-SW4w-dr^u2QMwGx539r0||| QDcD3N6`#z1=RRov1M{2HSpWb4 delta 657 zcmYL`PiPZC6vn^VEG8*2o93U{6ly??pr&TCO(`gN&{HldNIfW+HGd0DvY540si}pc zD1wnWst5%^P@%XGPgU@wXg!Dr1r?;1J$NXhpiqc!vWf%W`_1>}z2WWbhimN7Ro30H za2a6702E6N!wjz8tdd^=q<5uRD@A!)<3A__t7ffncI@{>ATN^*)Qq-C`4F9dBl>DH z7pkH1>K;H|0``{c6{Ea6^Zo{~-=Xt~IwgD&xd3ESq8j*|aGKGifDm9@Lc5%QZf;F{TLTOWu0uK@iG4ZYnwS1~)i13lny z=+>`O>@z>XS|^vms2R8e&tSKYI7H>kkRj#|zy}Gkv(+H;m4&-UX;8_U{FBA4_1Po_B>or=q3^b>79hcdpX0dAQ*N9!H6pe zMqNQL;R-RL>I!jU+7-4DCtZPR=?l@n=Xq*(<;A3(Nv(%Q7q5G)Gs?lAP(0#i;OqUD zv;WD*v{BIq`T5`162@IBH#L=C(suEV=H-vIL&;zu_(fR?eGkuvS0Yo { +export const useAnimationTruthOrDare = (wordsArr: string[]) => { const animContainer = useRef(new Animated.Value(400)).current + const { i18n } = useTranslation() - const startAnimation = () => { + const animValues: Animated.Value[] = [] + + wordsArr.forEach((_, index) => (animValues[index] = new Animated.Value(0))) + + const startAnimTextByVoice = () => { + const animations = wordsArr.map((word, index) => { + const wordWithComma = word.includes(',') + + const isEnLanguage = i18n.language === Language.EN + + const duration = isEnLanguage ? 50 : 75 + + const durationWithComma = Platform.select({ + android: 75, + default: isEnLanguage ? 175 : 100, + }) + + return Animated.timing(animValues[index], { + toValue: 1, + duration: + word.length * + (wordWithComma ? durationWithComma : duration), + useNativeDriver: true, + }) + }) + + Animated.sequence(animations).start() + } + + const startAnimationCard = () => { Animated.timing(animContainer, { toValue: 0, duration: 400, @@ -21,7 +53,9 @@ export const useAnimationTruthOrDare = () => { } return { - startAnimation, + startAnimationCard, + startAnimTextByVoice, + animValues, animStyle: animStyleContainer, } } diff --git a/src/module/game/components/index.ts b/src/module/game/components/index.ts index 6ffa9b6..0f141c9 100644 --- a/src/module/game/components/index.ts +++ b/src/module/game/components/index.ts @@ -1,2 +1,2 @@ -export * from './truth-or-dare-view' +export * from './truth-or-dare' export * from './player-field.component'; diff --git a/src/module/game/components/player-field.component.tsx b/src/module/game/components/player-field.component.tsx index ed19195..6602a97 100644 --- a/src/module/game/components/player-field.component.tsx +++ b/src/module/game/components/player-field.component.tsx @@ -24,7 +24,7 @@ export const PlayerField: FC = ({ value, onChange, onDelete }) => { onChange={onChange} renderPostfix={renderClear} inputProps={{ - placeholder: t('customPack.placeholder'), + placeholder: t('common.placeholderPlayer'), placeholderTextColor: colors.darkPurple, }} inputStyle={styles.input} diff --git a/src/module/game/components/truth-or-dare-view.tsx b/src/module/game/components/truth-or-dare-view.tsx deleted file mode 100644 index 03c297f..0000000 --- a/src/module/game/components/truth-or-dare-view.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React, { useEffect } from 'react' -import { Font, Icon, colors } from '../../common' -import { Animated, StyleSheet } from 'react-native' -import { useAnimationTruthOrDare } from '../animations' - -interface IProps { - item: string -} - -export const TruthOrDareView: React.FC = ({ item }) => { - const { animStyle, startAnimation } = useAnimationTruthOrDare() - - useEffect(() => { - startAnimation() - }, []) - return ( - - - {item} - - ) -} - -const styles = StyleSheet.create({ - container: { - paddingHorizontal: 16, - paddingVertical: 32, - backgroundColor: colors.darkPurple, - borderRadius: 20, - alignItems: 'center', - shadowColor: '#190f42', - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 1, - shadowRadius: 4, - elevation: 5, - marginTop: 88, - }, - starIcon: { - marginBottom: 14, - }, - text: { - color: colors.purple, - fontSize: 22, - lineHeight: 32, - textAlign: 'center', - fontFamily: Font.Roboto400, - }, -}) diff --git a/src/module/game/components/truth-or-dare.tsx b/src/module/game/components/truth-or-dare.tsx new file mode 100644 index 0000000..e6c6419 --- /dev/null +++ b/src/module/game/components/truth-or-dare.tsx @@ -0,0 +1,104 @@ +import React, { useEffect, useState } from 'react' +import { Font, Icon, StorageKey, colors, storageService } from '../../common' +import { Animated, StyleSheet, View } from 'react-native' +import { useAnimationTruthOrDare } from '../animations' +import Tts from 'react-native-tts' + +interface IProps { + item: string +} + +export const TruthOrDare: React.FC = ({ item }) => { + const wordsArr = item.trim().split(' ') + const [voiceover, setVoiceover] = useState(true) + + const { animStyle, animValues, startAnimationCard, startAnimTextByVoice } = + useAnimationTruthOrDare(wordsArr) + + useEffect(() => { + startAnimationCard() + + checkAndStartVoiceover() + }, [item]) + + const checkAndStartVoiceover = async () => { + const isVoicer = await storageService.get(StorageKey.Voiceover) + + setVoiceover(isVoicer) + + if (isVoicer) { + Tts.stop() + Tts.speak(item) + Tts.addEventListener('tts-start', startAnimTextByVoice) + } + } + + return ( + + + + {wordsArr?.map((word, index) => { + return ( + + {word + ' '} + + ) + })} + + + ) +} + +const styles = StyleSheet.create({ + container: { + paddingLeft: 21, + paddingRight: 11, + paddingVertical: 32, + backgroundColor: colors.darkPurple, + borderRadius: 20, + alignItems: 'center', + shadowColor: '#190f42', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 1, + shadowRadius: 4, + elevation: 5, + marginTop: 88, + }, + textWrap: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + }, + starIcon: { + marginBottom: 14, + }, + text: { + color: colors.purple, + fontSize: 22, + lineHeight: 32, + textAlign: 'center', + fontFamily: Font.Roboto400, + }, +}) diff --git a/src/module/game/config/index.ts b/src/module/game/config/index.ts index c5e6cc5..aaa99d3 100644 --- a/src/module/game/config/index.ts +++ b/src/module/game/config/index.ts @@ -1 +1,2 @@ export * from './package-name.config'; +export * from './voice.config'; diff --git a/src/module/game/config/voice.config.ts b/src/module/game/config/voice.config.ts new file mode 100644 index 0000000..a94fc1b --- /dev/null +++ b/src/module/game/config/voice.config.ts @@ -0,0 +1,12 @@ +import { Language } from '~module/common' + +export const voiceConfig: any = { + [Language.UA]: { + language: 'uk-UA', + voice: 'com.apple.voice.compact.uk-UA.Lesya', + }, + [Language.EN]: { + language: 'en-US', + voice: 'com.apple.ttsbundle.Samantha-compact', + }, +} diff --git a/src/module/game/hooks/get-current-truth-dares.hook.tsx b/src/module/game/hooks/get-current-truth-dares.hook.tsx index 41623ad..d9f194b 100644 --- a/src/module/game/hooks/get-current-truth-dares.hook.tsx +++ b/src/module/game/hooks/get-current-truth-dares.hook.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react' +import { useEffect, useMemo } from 'react' import { resetStepsByTruthOrDare, selectCustomPackage, @@ -64,8 +64,12 @@ export const useGetCurrentTruthOrDare = ({ return packageTruthsOrDares?.[currentStep]?.[i18n.language as Language] } - const customTruthsOrDares = getGameItemsByCustomPackage() - const packageTruthsOrDares = getGameItemsByPackage() + const customTruthsOrDares = useMemo(getGameItemsByCustomPackage, [ + customPackageShuffle, + customType, + ]) + + const packageTruthsOrDares = useMemo(getGameItemsByPackage, [gameItems]) const currentItem = getCurrentItem() const shuffleAndSavePackage = async () => { @@ -136,7 +140,7 @@ export const useGetCurrentTruthOrDare = ({ useEffect(() => { checkIsNeedShuffle() - }, [currentStep, customTruthsOrDares]) + }, [currentStep]) return currentItem } diff --git a/src/module/game/hooks/index.ts b/src/module/game/hooks/index.ts index 438ce0a..3199ece 100644 --- a/src/module/game/hooks/index.ts +++ b/src/module/game/hooks/index.ts @@ -1,2 +1,3 @@ export * from './get-current-truth-dares.hook' export * from './use-set-steps-by-package'; +export * from './use-voice.hook'; diff --git a/src/module/game/hooks/use-voice.hook.tsx b/src/module/game/hooks/use-voice.hook.tsx new file mode 100644 index 0000000..269cfe9 --- /dev/null +++ b/src/module/game/hooks/use-voice.hook.tsx @@ -0,0 +1,42 @@ +import { useEffect, useState } from 'react' +import Tts from 'react-native-tts' +import { voiceConfig } from '../config' +import { useTranslation } from 'react-i18next' + +export const useVoice = () => { + const { i18n } = useTranslation() + const [ttsStatus, setTtsStatus] = useState('initiliazing') + + useEffect(() => { + Tts.addEventListener('tts-finish', _event => setTtsStatus('finished')) + Tts.addEventListener('tts-cancel', _event => setTtsStatus('cancelled')) + Tts.getInitStatus().then(initTts) + + return () => { + if (ttsStatus === 'finished') { + Tts.removeEventListener('tts-start', _event => + setTtsStatus('started'), + ) + } + + Tts.removeEventListener('tts-finish', _event => + setTtsStatus('finished'), + ) + Tts.removeEventListener('tts-cancel', _event => + setTtsStatus('cancelled'), + ) + } + }, []) + + const initTts = async () => { + try { + await Tts.setDefaultLanguage(voiceConfig[i18n.language].language) + await Tts.setDefaultVoice(voiceConfig[i18n.language].voice) + await Tts.setDefaultRate(0.5) + } catch (err) { + //Samsung S9 has always this error: + //"Language is not supported" + console.log(`setDefaultLanguage error `, err) + } + } +} diff --git a/src/module/game/screens/game.screen.tsx b/src/module/game/screens/game.screen.tsx index 8c5158a..2bb5dc4 100644 --- a/src/module/game/screens/game.screen.tsx +++ b/src/module/game/screens/game.screen.tsx @@ -17,7 +17,7 @@ import { useIsFocused, useRoute } from '@react-navigation/native' import { useAnimationButton } from '../animations' import { PlayerName } from '../components/player-name.component' import { packageNameConfig } from '../config' -import { useSetStepsByPackage } from '../hooks' +import { useSetStepsByPackage, useVoice } from '../hooks' interface IRouteParams { packageType?: PackageType @@ -33,6 +33,8 @@ export const GameScreen: FC = () => { useSetStepsByPackage(packageType) + useVoice() + const randomGame = () => { const isTruthRandom = Math.random() < 0.5 const customRandom = isTruthRandom diff --git a/src/module/game/screens/players.screen.tsx b/src/module/game/screens/players.screen.tsx index 7bb853d..b51219a 100644 --- a/src/module/game/screens/players.screen.tsx +++ b/src/module/game/screens/players.screen.tsx @@ -37,7 +37,7 @@ export const PlayersScreen: FC = () => { const onDeletePlayer = (index: number) => { const updatedPlayers = [...players] - if (updatedPlayers.length === 1) return + if (updatedPlayers.length <= 2) return updatedPlayers.splice(index, 1) dispatch(setPlayers(updatedPlayers)) @@ -66,16 +66,13 @@ export const PlayersScreen: FC = () => { +

}> - + {players.map((player, index) => ( { onDelete={() => onDeletePlayer(index)} /> ))} + - - { dispatch(onNextPlayer()) dispatch(nextStep(choiceType)) saveLastStep() + Tts.stop() } const onAddGameItemToCustomPackage = () => { @@ -67,6 +69,7 @@ export const TruthOrDareScreen: React.FC = () => { } const onPressAddPlus = () => { + Tts.stop() const subtitleByChoice = choiceType === ChoiceType.Truth ? t('customPack.addCustomTruth') @@ -157,7 +160,7 @@ export const TruthOrDareScreen: React.FC = () => { - + {currentItem ? : null} { animation={animScale.func} animStyle={animScale.style} /> - - + {packageType !== PackageType.Custom && ( + + )} diff --git a/src/module/packages/animation/use-animation-list.hook.ts b/src/module/packages/animation/use-animation-list.hook.ts index c16b1b7..61358f8 100644 --- a/src/module/packages/animation/use-animation-list.hook.ts +++ b/src/module/packages/animation/use-animation-list.hook.ts @@ -1,10 +1,7 @@ import React, { useEffect, useRef } from 'react' import { Animated } from 'react-native' -import { useIsFocused } from '@react-navigation/native' export const useAnimationList = (delay: number) => { - const isFocus = useIsFocused() - const animTransformX = useRef(new Animated.Value(0)).current const animTransformY = useRef(new Animated.Value(0)).current @@ -33,12 +30,8 @@ export const useAnimationList = (delay: number) => { ), ]) - if (!isFocus) { - return animation.reset() - } - animation.start() - }, [isFocus]) + }, []) const animationStyleItem = { opacity: animTransformX, diff --git a/src/module/packages/atoms/packages-page-separator.atom.tsx b/src/module/packages/atoms/packages-page-separator.atom.tsx index 017031e..7ac2b63 100644 --- a/src/module/packages/atoms/packages-page-separator.atom.tsx +++ b/src/module/packages/atoms/packages-page-separator.atom.tsx @@ -8,20 +8,17 @@ export const PackagesPageSeparator = () => { useEffect(() => { Animated.spring(fadeInAnim, { toValue: 1, - useNativeDriver: true, - delay: 1100, + useNativeDriver: false, + stiffness: 50, + delay: 1400, }).start() }, []) const animStyle = { - transform: [ - { - translateY: fadeInAnim.interpolate({ - inputRange: [0, 1], - outputRange: [-900, 0], - }), - }, - ], + width: fadeInAnim.interpolate({ + inputRange: [0, 1], + outputRange: ['0%', '100%'], + }), } return ( diff --git a/src/module/root/navigations-groups/user.group.tsx b/src/module/root/navigations-groups/user.group.tsx index 41d0a52..e02d2d3 100644 --- a/src/module/root/navigations-groups/user.group.tsx +++ b/src/module/root/navigations-groups/user.group.tsx @@ -35,6 +35,7 @@ export const UserNavigationGroup: FC = () => { { return await storageService.get(StorageKey.FinishOnBoarding) } + const setVoiceover = async () => { + const isVoiceover = await storageService.get(StorageKey.Voiceover) + + if (isVoiceover === null) { + await storageService.set(StorageKey.Voiceover, true) + } + } + const init = async () => { const language = await getLanguage() const isOnBoard = await getOnboardEnd() @@ -56,6 +64,7 @@ export const LoadingScreen: FC = () => { useEffect(() => { init() + setVoiceover() }, []) return ( diff --git a/src/module/settings/atoms/index.ts b/src/module/settings/atoms/index.ts index 06c290f..50e0737 100644 --- a/src/module/settings/atoms/index.ts +++ b/src/module/settings/atoms/index.ts @@ -1,3 +1,4 @@ export * from './selected-language-in-settings.atom' export * from './switch-notifications.atom' export * from './purchases.atom' +export * from './switch-voiceover.atom'; diff --git a/src/module/settings/atoms/switch-notifications.atom.tsx b/src/module/settings/atoms/switch-notifications.atom.tsx index eb834a3..4b47e5d 100644 --- a/src/module/settings/atoms/switch-notifications.atom.tsx +++ b/src/module/settings/atoms/switch-notifications.atom.tsx @@ -6,7 +6,7 @@ export const SwitchNotificationsAtom = () => { const [isEnabled, setIsEnabled] = useState(true) const toggleSwitch = () => { - setIsEnabled(previousState => !previousState) + setIsEnabled(!isEnabled) } return ( diff --git a/src/module/settings/atoms/switch-voiceover.atom.tsx b/src/module/settings/atoms/switch-voiceover.atom.tsx new file mode 100644 index 0000000..e00a661 --- /dev/null +++ b/src/module/settings/atoms/switch-voiceover.atom.tsx @@ -0,0 +1,33 @@ +import React, { useEffect, useState } from 'react' +import { Switch } from 'react-native' +import { StorageKey, colors, storageService } from '../../common' + +export const SwitchVoiceoverAtom = () => { + const [voiceover, setVoiceover] = useState(true) + + const toggleSwitch = async () => { + setVoiceover(!voiceover) + await storageService.set(StorageKey.Voiceover, !voiceover) + } + + const getIsVoiceover = async () => { + const isVoiceover = await storageService.get(StorageKey.Voiceover) + + setVoiceover(isVoiceover) + } + + useEffect(() => { + getIsVoiceover() + }, []) + + return ( + + ) +} diff --git a/src/module/settings/config/settings.config.tsx b/src/module/settings/config/settings.config.tsx index 2c58c76..42ac54f 100644 --- a/src/module/settings/config/settings.config.tsx +++ b/src/module/settings/config/settings.config.tsx @@ -1,6 +1,10 @@ import React from 'react' import { SettingLocale } from '../../../i18n/interfaces/settings.types.interface' -import { SelectedLanguage, SwitchNotificationsAtom } from '../atoms' +import { + SelectedLanguage, + SwitchNotificationsAtom, + SwitchVoiceoverAtom, +} from '../atoms' const translatePath = (itemKey: keyof SettingLocale.Core) => `settingTranslation.${itemKey}` @@ -20,6 +24,11 @@ export const settingsConfig = [ image: 'notification', component: () => , }, + { + title: translatePath('voiceover'), + image: 'music', + component: () => , + }, { title: translatePath('write'), image: 'message', diff --git a/src/module/settings/screens/settings.screen.tsx b/src/module/settings/screens/settings.screen.tsx index 58021a8..b6cd1ad 100644 --- a/src/module/settings/screens/settings.screen.tsx +++ b/src/module/settings/screens/settings.screen.tsx @@ -67,6 +67,8 @@ export const SettingsScreen: FC = () => { break case 'notification': break + case 'voice': + break case 'message': nav.navigate(UserRouteKey.WriteToUs) break diff --git a/src/store/slices/players.slice.ts b/src/store/slices/players.slice.ts index 0b51e48..bb966a2 100644 --- a/src/store/slices/players.slice.ts +++ b/src/store/slices/players.slice.ts @@ -7,22 +7,18 @@ export interface PlayersState { players: string[] playerIndex: number currentPlayer: string - loaded: boolean - hasError: boolean } const initialState: PlayersState = { players: [], playerIndex: 0, currentPlayer: '', - loaded: false, - hasError: false, } export const getPlayersAsync = createAsyncThunk('get-players', async () => { const savedPlayers = await storageService.get(StorageKey.Players) - return savedPlayers ? savedPlayers : [''] + return savedPlayers ? savedPlayers : ['', ''] }) export const playersSlice = createSlice({ @@ -47,17 +43,10 @@ export const playersSlice = createSlice({ }, }, extraReducers(builder) { - builder - .addCase(getPlayersAsync.fulfilled, (state, action) => { - state.players = action.payload - state.currentPlayer = state.players[0] - }) - .addCase(getPlayersAsync.pending, state => { - state.loaded = false - }) - .addCase(getPlayersAsync.rejected, state => { - state.hasError = true - }) + builder.addCase(getPlayersAsync.fulfilled, (state, action) => { + state.players = action.payload + state.currentPlayer = state.players[0] + }) }, })