Browse Source

FEATURE | Add players & questions and dares for packages (#5)

Co-authored-by: Vlad <vlad960706@gmail.com>
Reviewed-on: #5
Co-authored-by: Vlad Narizhnyi <vlad960706@gmail.com>
Co-committed-by: Vlad Narizhnyi <vlad960706@gmail.com>
pull/6/head
Vlad Narizhnyi 11 months ago committed by Vitalik Yatsenko
parent
commit
b4bb3193d9
  1. 4
      android/app/google-services.json
  2. 1
      android/app/src/main/AndroidManifest.xml
  3. BIN
      android/app/src/main/ic_launcher-playstore.png
  4. BIN
      android/app/src/main/res/drawable-mdpi/splash_image.png
  5. BIN
      android/app/src/main/res/drawable-xhdpi/splash_image.png
  6. BIN
      android/app/src/main/res/drawable-xxhdpi/splash_image.png
  7. 0
      android/app/src/main/res/drawable/splash_screen.png
  8. 11
      android/app/src/main/res/drawable/splashscreen.xml
  9. 15
      android/app/src/main/res/layout/launch_screen.xml
  10. 11
      android/app/src/main/res/layout/splash_screen.xml
  11. 5
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  12. 5
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  13. BIN
      android/app/src/main/res/mipmap-hdpi-v26/ic_foreground.png
  14. 4
      android/app/src/main/res/mipmap-hdpi-v26/ic_launcher.xml
  15. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  16. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
  17. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  18. BIN
      android/app/src/main/res/mipmap-ldpi-v26/ic_foreground.png
  19. 4
      android/app/src/main/res/mipmap-ldpi-v26/ic_launcher.xml
  20. BIN
      android/app/src/main/res/mipmap-ldpi/ic_launcher.png
  21. BIN
      android/app/src/main/res/mipmap-mdpi-v26/ic_foreground.png
  22. 4
      android/app/src/main/res/mipmap-mdpi-v26/ic_launcher.xml
  23. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  24. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
  25. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  26. BIN
      android/app/src/main/res/mipmap-xhdpi-v26/ic_foreground.png
  27. 4
      android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher.xml
  28. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  29. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
  30. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  31. BIN
      android/app/src/main/res/mipmap-xxhdpi-v26/ic_foreground.png
  32. 4
      android/app/src/main/res/mipmap-xxhdpi-v26/ic_launcher.xml
  33. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  34. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
  35. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  36. BIN
      android/app/src/main/res/mipmap-xxxhdpi-v26/ic_foreground.png
  37. 4
      android/app/src/main/res/mipmap-xxxhdpi-v26/ic_launcher.xml
  38. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  39. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
  40. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  41. 3
      android/app/src/main/res/values/colors-icon.xml
  42. 4
      android/app/src/main/res/values/colors-splash.xml
  43. 4
      android/app/src/main/res/values/ic_launcher_background.xml
  44. 2
      android/app/src/main/res/values/strings.xml
  45. 6
      android/app/src/main/res/values/styles.xml
  46. 6
      android/build.gradle
  47. 8
      index.js
  48. 18
      ios/GoogleService-Info.plist
  49. 3
      ios/Podfile
  50. 2
      ios/Podfile.lock
  51. 14
      ios/Truth.xcodeproj/project.pbxproj
  52. 4
      src/config/fontello.json
  53. 9
      src/i18n/interfaces/common.interface.ts
  54. 2
      src/i18n/interfaces/custom-pack.interface.ts
  55. 1
      src/i18n/interfaces/page-titles.interface.ts
  56. 12
      src/i18n/locales/en/common.translation.ts
  57. 18
      src/i18n/locales/en/custom-pack.translation.ts
  58. 2
      src/i18n/locales/en/onBoardingButton.translation.ts
  59. 1
      src/i18n/locales/en/page-title.translation.ts
  60. 4
      src/i18n/locales/en/steps.translation.ts
  61. 2
      src/i18n/locales/hi/onBoardingButton.translation.ts
  62. 9
      src/i18n/locales/ua/common.translation.ts
  63. 18
      src/i18n/locales/ua/custom-pack.translation.ts
  64. 2
      src/i18n/locales/ua/onBoardingButton.translation.ts
  65. 1
      src/i18n/locales/ua/page-title.translation.ts
  66. 2
      src/i18n/locales/ua/purchases.translation.ts
  67. 2
      src/i18n/locales/ua/settings.translation.ts
  68. 35
      src/i18n/locales/ua/step.translation.ts
  69. 2
      src/module/common/components/buttons/button-primary.component.tsx
  70. 1
      src/module/common/components/form/form-controll-wrap.component.tsx
  71. 13
      src/module/common/components/form/form-text-controll.component.tsx
  72. 41
      src/module/common/components/header/header.component.tsx
  73. 2
      src/module/common/hooks/index.ts
  74. 4
      src/module/common/hooks/use-dispatch.hook.ts
  75. 5
      src/module/common/hooks/use-selector.hook.ts
  76. 1
      src/module/common/index.ts
  77. 746
      src/module/common/questions-dares-list/questions-dares-list.ts
  78. 1
      src/module/common/services/index.ts
  79. 34
      src/module/common/services/storage.service.ts
  80. 4
      src/module/common/typing/enums/choice-type.enum.ts
  81. 2
      src/module/common/typing/enums/custom-type.enum.ts
  82. 5
      src/module/common/typing/enums/guest-route-keys.enum.ts
  83. 11
      src/module/common/typing/enums/index.ts
  84. 4
      src/module/common/typing/enums/nav-group.enum.ts
  85. 6
      src/module/common/typing/enums/package-type.enum.ts
  86. 2
      src/module/common/typing/enums/products.enum.ts
  87. 8
      src/module/common/typing/enums/storage-key.enum.ts
  88. 6
      src/module/common/typing/enums/user-route-keys.enum.ts
  89. 14
      src/module/common/typing/interfaces/game-item.ts
  90. 1
      src/module/custom-package/animation/index.ts
  91. 53
      src/module/custom-package/animation/use-animation-block.hook.tsx
  92. 61
      src/module/custom-package/atoms/custom-block.atom.tsx
  93. 1
      src/module/custom-package/index.ts
  94. 92
      src/module/custom-package/screens/custom-package-editor.screen.tsx
  95. 41
      src/module/custom-package/screens/custom-package-play.screen.tsx
  96. 35
      src/module/game/animations/use-animation-button.ts
  97. 63
      src/module/game/animations/use-animation-truth-or-dare.hook.ts
  98. 1
      src/module/game/components/index.ts
  99. 49
      src/module/game/components/player-field.component.tsx
  100. 22
      src/module/game/components/player-name.component.tsx
  101. Some files were not shown because too many files have changed in this diff Show More

4
android/app/google-services.json

@ -1,8 +1,8 @@
{ {
"project_info": { "project_info": {
"project_number": "180425292880", "project_number": "552568521005",
"firebase_url": "https://truthordare-6493e-default-rtdb.europe-west1.firebasedatabase.app", "firebase_url": "https://truthordare-6493e-default-rtdb.europe-west1.firebasedatabase.app",
"project_id": "truthordare-6493e", "project_id": "truth-or-dare-fcc54",
"storage_bucket": "truthordare-6493e.appspot.com" "storage_bucket": "truthordare-6493e.appspot.com"
}, },
"client": [ "client": [

1
android/app/src/main/AndroidManifest.xml

@ -7,7 +7,6 @@
android:name=".MainApplication" android:name=".MainApplication"
android:label="@string/app_name" android:label="@string/app_name"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false" android:allowBackup="false"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">

BIN
android/app/src/main/ic_launcher-playstore.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
android/app/src/main/res/drawable-mdpi/splash_image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

BIN
android/app/src/main/res/drawable-xhdpi/splash_image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

BIN
android/app/src/main/res/drawable-xxhdpi/splash_image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

0
android/app/src/main/res/drawable-hdpi/splash_image.png → android/app/src/main/res/drawable/splash_screen.png

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

11
android/app/src/main/res/drawable/splashscreen.xml

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/splashprimary" />
<item>
<bitmap
android:gravity="center"
android:src="@drawable/splash_image" />
</item>
</layer-list>

15
android/app/src/main/res/layout/launch_screen.xml

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:contentDescription="Splashscreen"
android:scaleType="fitCenter"
android:background="@color/splashprimary"
android:src="@drawable/splashscreen"/>
</RelativeLayout>

11
android/app/src/main/res/layout/splash_screen.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/splash_screen"
android:scaleType="centerCrop"
/>
</RelativeLayout>

5
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

5
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-hdpi-v26/ic_foreground.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

4
android/app/src/main/res/mipmap-hdpi-v26/ic_launcher.xml

@ -1,4 +0,0 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
android/app/src/main/res/mipmap-ldpi-v26/ic_foreground.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

4
android/app/src/main/res/mipmap-ldpi-v26/ic_launcher.xml

@ -1,4 +0,0 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-ldpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

BIN
android/app/src/main/res/mipmap-mdpi-v26/ic_foreground.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

4
android/app/src/main/res/mipmap-mdpi-v26/ic_launcher.xml

@ -1,4 +0,0 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
android/app/src/main/res/mipmap-xhdpi-v26/ic_foreground.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

4
android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher.xml

@ -1,4 +0,0 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
android/app/src/main/res/mipmap-xxhdpi-v26/ic_foreground.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

4
android/app/src/main/res/mipmap-xxhdpi-v26/ic_launcher.xml

@ -1,4 +0,0 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
android/app/src/main/res/mipmap-xxxhdpi-v26/ic_foreground.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

4
android/app/src/main/res/mipmap-xxxhdpi-v26/ic_launcher.xml

@ -1,4 +0,0 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

3
android/app/src/main/res/values/colors-icon.xml

@ -1,3 +0,0 @@
<resources>
<color name ='iconBackground'>#37296B</color>
</resources>

4
android/app/src/main/res/values/colors-splash.xml

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splashprimary">#37296B</color>
</resources>

4
android/app/src/main/res/values/ic_launcher_background.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#37296B</color>
</resources>

2
android/app/src/main/res/values/strings.xml

@ -1,3 +1,3 @@
<resources> <resources>
<string name="app_name">Truth</string> <string name="app_name">Truth or Dare</string>
</resources> </resources>

6
android/app/src/main/res/values/styles.xml

@ -1,12 +1,10 @@
<resources> <resources>
<style name="SplashScreenTheme" parent="SplashScreen_SplashTheme">
<item name="colorPrimaryDark">@color/splashprimary</item>
</style>
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item> <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
</style> </style>

6
android/build.gradle

@ -20,9 +20,9 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath("com.android.tools.build:gradle") classpath "com.android.tools.build:gradle"
classpath("com.facebook.react:react-native-gradle-plugin") classpath "com.facebook.react:react-native-gradle-plugin"
classpath ("com.google.gms:google-services:4.3.14") classpath 'com.google.gms:google-services:4.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

8
index.js

@ -2,8 +2,8 @@
* @format * @format
*/ */
import {AppRegistry} from 'react-native'; import { AppRegistry } from 'react-native'
import App from './App'; import App from './App'
import {name as appName} from './app.json'; import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App); AppRegistry.registerComponent(appName, () => App)

18
ios/GoogleService-Info.plist

@ -2,22 +2,18 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CLIENT_ID</key>
<string>180425292880-bfueoq3p0oq0b0lf2qviebio2q338eu8.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.180425292880-bfueoq3p0oq0b0lf2qviebio2q338eu8</string>
<key>API_KEY</key> <key>API_KEY</key>
<string>AIzaSyDsJWXu0NtusG6fric25R8zN-j-LSHd_tg</string> <string>AIzaSyDmYx2wadrC7tLUI-eS_tgUVuH0GrB_4mE</string>
<key>GCM_SENDER_ID</key> <key>GCM_SENDER_ID</key>
<string>180425292880</string> <string>552568521005</string>
<key>PLIST_VERSION</key> <key>PLIST_VERSION</key>
<string>1</string> <string>1</string>
<key>BUNDLE_ID</key> <key>BUNDLE_ID</key>
<string>org.reactjs.native.example.Truth</string> <string>com.truth</string>
<key>PROJECT_ID</key> <key>PROJECT_ID</key>
<string>truthordare-6493e</string> <string>truth-or-dare-fcc54</string>
<key>STORAGE_BUCKET</key> <key>STORAGE_BUCKET</key>
<string>truthordare-6493e.appspot.com</string> <string>truth-or-dare-fcc54.appspot.com</string>
<key>IS_ADS_ENABLED</key> <key>IS_ADS_ENABLED</key>
<false></false> <false></false>
<key>IS_ANALYTICS_ENABLED</key> <key>IS_ANALYTICS_ENABLED</key>
@ -29,8 +25,6 @@
<key>IS_SIGNIN_ENABLED</key> <key>IS_SIGNIN_ENABLED</key>
<true></true> <true></true>
<key>GOOGLE_APP_ID</key> <key>GOOGLE_APP_ID</key>
<string>1:180425292880:ios:7109aea721588b757da555</string> <string>1:552568521005:ios:66c16d5229fe90142353a4</string>
<key>DATABASE_URL</key>
<string>https://truthordare-6493e-default-rtdb.europe-west1.firebasedatabase.app</string>
</dict> </dict>
</plist> </plist>

3
ios/Podfile

@ -18,7 +18,8 @@ flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : Flip
linkage = ENV['USE_FRAMEWORKS'] linkage = ENV['USE_FRAMEWORKS']
if linkage != nil if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
use_frameworks! :linkage => linkage.to_sym use_frameworks! :linkage => :static
$RNFirebaseAsStaticFramework = true
end end
target 'Truth' do target 'Truth' do

2
ios/Podfile.lock

@ -1588,6 +1588,6 @@ SPEC CHECKSUMS:
Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5 Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: ce2deb38e840b0f84d5baf01ec7da0d590e1e158 PODFILE CHECKSUM: 0c63220a19ca9fd3d2ce02dc5eecdb8c820bf5ab
COCOAPODS: 1.12.1 COCOAPODS: 1.12.1

14
ios/Truth.xcodeproj/project.pbxproj

@ -11,10 +11,10 @@
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
3F5CDF352995282400BD4B7F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3F5CDF342995282400BD4B7F /* GoogleService-Info.plist */; };
52BCE0F228C76D5A008C74BC /* Fonts in Resources */ = {isa = PBXBuildFile; fileRef = 52BCE0EE28C76941008C74BC /* Fonts */; }; 52BCE0F228C76D5A008C74BC /* Fonts in Resources */ = {isa = PBXBuildFile; fileRef = 52BCE0EE28C76941008C74BC /* Fonts */; };
52BCE0F328C77143008C74BC /* fontello.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DA10DFDF3E05483BA976401B /* fontello.ttf */; }; 52BCE0F328C77143008C74BC /* fontello.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DA10DFDF3E05483BA976401B /* fontello.ttf */; };
63120D812B0DE8C900E76BCD /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63120D802B0DE8C900E76BCD /* StoreKit.framework */; }; 63120D812B0DE8C900E76BCD /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63120D802B0DE8C900E76BCD /* StoreKit.framework */; };
6318D32F2B459A5D0034E561 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6318D32E2B459A5D0034E561 /* GoogleService-Info.plist */; };
637B62A42B07BAFB008D8917 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 637B62A32B07BAFB008D8917 /* Roboto-Bold.ttf */; }; 637B62A42B07BAFB008D8917 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 637B62A32B07BAFB008D8917 /* Roboto-Bold.ttf */; };
637B62A62B07BB0B008D8917 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 637B62A52B07BB0B008D8917 /* Roboto-Regular.ttf */; }; 637B62A62B07BB0B008D8917 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 637B62A52B07BB0B008D8917 /* Roboto-Regular.ttf */; };
8D22E0E3287C39ED0031C6E5 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8D22E0E2287C39ED0031C6E5 /* Launch Screen.storyboard */; }; 8D22E0E3287C39ED0031C6E5 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8D22E0E2287C39ED0031C6E5 /* Launch Screen.storyboard */; };
@ -46,9 +46,9 @@
28F2047B035775EA39D23C93 /* libPods-Truth-TruthTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Truth-TruthTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 28F2047B035775EA39D23C93 /* libPods-Truth-TruthTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Truth-TruthTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
36C7150ADAB54DA0B3D10FF5 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Roboto-Bold.ttf"; path = "../src/assets/resources/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; }; 36C7150ADAB54DA0B3D10FF5 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Roboto-Bold.ttf"; path = "../src/assets/resources/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; };
3F5CDF302995158300BD4B7F /* ios */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ios; sourceTree = "<group>"; }; 3F5CDF302995158300BD4B7F /* ios */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ios; sourceTree = "<group>"; };
3F5CDF342995282400BD4B7F /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
52BCE0EE28C76941008C74BC /* Fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Fonts; sourceTree = "<group>"; }; 52BCE0EE28C76941008C74BC /* Fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Fonts; sourceTree = "<group>"; };
63120D802B0DE8C900E76BCD /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; 63120D802B0DE8C900E76BCD /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
6318D32E2B459A5D0034E561 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../../../Downloads/GoogleService-Info.plist"; sourceTree = "<group>"; };
637B62A12B07B836008D8917 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Roboto-Regular.ttf"; path = "../src/assets/resources/fonts/Roboto-Regular.ttf"; sourceTree = "<group>"; }; 637B62A12B07B836008D8917 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Roboto-Regular.ttf"; path = "../src/assets/resources/fonts/Roboto-Regular.ttf"; sourceTree = "<group>"; };
637B62A22B07B836008D8917 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Roboto-Bold.ttf"; path = "../src/assets/resources/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; }; 637B62A22B07B836008D8917 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Roboto-Bold.ttf"; path = "../src/assets/resources/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; };
637B62A32B07BAFB008D8917 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Roboto-Bold.ttf"; path = "../src/assets/resources/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; }; 637B62A32B07BAFB008D8917 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Roboto-Bold.ttf"; path = "../src/assets/resources/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; };
@ -146,9 +146,9 @@
83CBB9F61A601CBA00E9B192 = { 83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6318D32E2B459A5D0034E561 /* GoogleService-Info.plist */,
637B62A52B07BB0B008D8917 /* Roboto-Regular.ttf */, 637B62A52B07BB0B008D8917 /* Roboto-Regular.ttf */,
637B62A32B07BAFB008D8917 /* Roboto-Bold.ttf */, 637B62A32B07BAFB008D8917 /* Roboto-Bold.ttf */,
3F5CDF342995282400BD4B7F /* GoogleService-Info.plist */,
3F5CDF302995158300BD4B7F /* ios */, 3F5CDF302995158300BD4B7F /* ios */,
13B07FAE1A68108700A75B9A /* Truth */, 13B07FAE1A68108700A75B9A /* Truth */,
832341AE1AAA6A7D00B99B32 /* Libraries */, 832341AE1AAA6A7D00B99B32 /* Libraries */,
@ -289,12 +289,12 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
637B62A62B07BB0B008D8917 /* Roboto-Regular.ttf in Resources */, 637B62A62B07BB0B008D8917 /* Roboto-Regular.ttf in Resources */,
6318D32F2B459A5D0034E561 /* GoogleService-Info.plist in Resources */,
637B62A42B07BAFB008D8917 /* Roboto-Bold.ttf in Resources */, 637B62A42B07BAFB008D8917 /* Roboto-Bold.ttf in Resources */,
52BCE0F328C77143008C74BC /* fontello.ttf in Resources */, 52BCE0F328C77143008C74BC /* fontello.ttf in Resources */,
52BCE0F228C76D5A008C74BC /* Fonts in Resources */, 52BCE0F228C76D5A008C74BC /* Fonts in Resources */,
8D22E0E3287C39ED0031C6E5 /* Launch Screen.storyboard in Resources */, 8D22E0E3287C39ED0031C6E5 /* Launch Screen.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
3F5CDF352995282400BD4B7F /* GoogleService-Info.plist in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -749,7 +749,8 @@
OTHER_CPLUSPLUSFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
" ", "-Wl",
"-ld_classic",
); );
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -825,7 +826,8 @@
OTHER_CPLUSPLUSFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
" ", "-Wl",
"-ld_classic",
); );
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;

4
src/config/fontello.json

@ -236,7 +236,7 @@
}, },
{ {
"uid": "c0f00bfaafecf771a588798f5995fee2", "uid": "c0f00bfaafecf771a588798f5995fee2",
"css": "settings", "css": "players",
"code": 59411, "code": 59411,
"src": "custom_icons", "src": "custom_icons",
"selected": true, "selected": true,
@ -244,7 +244,7 @@
"path": "M78.6 162.7C78.6 79.4 146.1 11.4 230 11.4 313.8 11.4 381.4 78.9 381.4 162.7 381.4 244.7 316.8 311.1 235.8 314.1 233.9 314.1 232.1 314.1 230.2 313.8 228.4 314.1 226.5 314.1 224.7 314.1 143.6 311.1 79.2 244.7 78.6 163L78.6 162.7ZM146.8 162.6C147.2 207.2 181.5 243 224.7 245.8 228.4 245.5 232.1 245.5 235.7 245.8 279 243 313.2 207.2 313.2 162.7 313.2 116.6 276.2 79.5 230 79.5 184 79.5 146.9 116.9 146.8 162.6ZM685.5 162.7C685.5 116.6 722.5 79.5 768.6 79.5 814.7 79.5 851.7 116.9 851.8 162.6 851.4 207.2 817.1 243 773.9 245.8 770.3 245.5 766.5 245.5 762.9 245.8 719.6 243 685.5 207.2 685.5 162.7ZM768.6 11.4C684.8 11.4 617.3 78.9 617.3 162.7 617.3 244.7 681.8 311.1 762.9 314.1 764.7 314.1 766.6 314.1 768.4 313.8 770.2 314.1 772.1 314.1 774 314.1 855 311.1 919.4 244.7 920 163H920V162.7C920 79.4 852.5 11.4 768.6 11.4ZM923.8 394.3C866.6 356.3 787.8 344.8 718.7 356.9 700.1 360.1 687.7 377.8 691 396.3 694.2 414.9 711.9 427.3 730.4 424 785.9 414.3 846.1 424.6 886.1 451.1 911 467.7 919 486.3 919 500.5 919 514.6 911 533.2 886.1 549.8L886 549.9C846.5 576.3 787.1 586.6 731.6 577.3 713 574.2 695.4 586.7 692.3 605.3 689.2 623.8 701.7 641.4 720.3 644.5 789.2 656.1 867 644.6 923.9 606.5 963.1 580.4 987.2 542.6 987.2 500.5 987.2 458.3 963.1 420.5 923.9 394.4L923.8 394.3ZM268.2 424C212.8 414.3 152.5 424.6 112.5 451.1 87.6 467.7 79.7 486.3 79.7 500.5 79.7 514.6 87.6 533.2 112.5 549.8L112.6 549.9C152.1 576.3 211.5 586.6 267.1 577.3 285.6 574.2 303.2 586.7 306.3 605.3 309.5 623.8 296.9 641.4 278.4 644.5 209.4 656.1 131.6 644.6 74.7 606.5 35.6 580.4 11.5 542.6 11.5 500.5 11.5 458.3 35.6 420.5 74.7 394.4L74.8 394.3C132.1 356.3 210.9 344.8 280 356.9 298.5 360.1 310.9 377.8 307.7 396.3 304.4 414.9 286.8 427.3 268.2 424ZM495.9 419.1C449.7 419.1 412.7 456.1 412.7 502.3 412.7 546.7 446.9 582.5 490.2 585.4 493.9 585 497.6 585 501.3 585.4 544.2 582.9 578.7 547 579.1 502.1 579 456.4 542 419.1 495.9 419.1ZM344.5 502.3C344.5 418.4 412.1 350.9 495.9 350.9 579.8 350.9 647.3 419 647.3 502.3V502.5H647.3C646.7 584.1 582.5 651.3 501 653.6 499.2 653.7 497.4 653.6 495.7 653.4 493.8 653.6 492 653.7 490.1 653.6 409.1 650.7 344.5 584.3 344.5 502.3ZM651.2 734.4C608.2 705.7 553.3 692.5 500.2 692.5 447 692.5 392 705.7 348.9 734.3L348.8 734.4C309.7 760.5 285.6 798.3 285.6 840.5 285.6 882.6 309.7 920.4 348.8 946.5 391.9 975.4 446.9 988.8 500 988.8 553.1 988.8 608.1 975.4 651.2 946.5 690.3 920.4 714.4 882.6 714.4 840.5 714.4 798.3 690.3 760.5 651.2 734.4ZM353.7 840.5C353.7 826.3 361.7 807.7 386.6 791.1 416.2 771.5 457.3 760.7 500.2 760.7 543.1 760.7 584 771.5 613.4 791.1 638.3 807.7 646.3 826.3 646.3 840.5 646.3 854.6 638.3 873.2 613.4 889.8L613.3 889.8C583.7 909.6 542.8 920.6 500 920.6 457.2 920.6 416.3 909.6 386.7 889.8L386.6 889.8C361.7 873.2 353.7 854.6 353.7 840.5Z", "path": "M78.6 162.7C78.6 79.4 146.1 11.4 230 11.4 313.8 11.4 381.4 78.9 381.4 162.7 381.4 244.7 316.8 311.1 235.8 314.1 233.9 314.1 232.1 314.1 230.2 313.8 228.4 314.1 226.5 314.1 224.7 314.1 143.6 311.1 79.2 244.7 78.6 163L78.6 162.7ZM146.8 162.6C147.2 207.2 181.5 243 224.7 245.8 228.4 245.5 232.1 245.5 235.7 245.8 279 243 313.2 207.2 313.2 162.7 313.2 116.6 276.2 79.5 230 79.5 184 79.5 146.9 116.9 146.8 162.6ZM685.5 162.7C685.5 116.6 722.5 79.5 768.6 79.5 814.7 79.5 851.7 116.9 851.8 162.6 851.4 207.2 817.1 243 773.9 245.8 770.3 245.5 766.5 245.5 762.9 245.8 719.6 243 685.5 207.2 685.5 162.7ZM768.6 11.4C684.8 11.4 617.3 78.9 617.3 162.7 617.3 244.7 681.8 311.1 762.9 314.1 764.7 314.1 766.6 314.1 768.4 313.8 770.2 314.1 772.1 314.1 774 314.1 855 311.1 919.4 244.7 920 163H920V162.7C920 79.4 852.5 11.4 768.6 11.4ZM923.8 394.3C866.6 356.3 787.8 344.8 718.7 356.9 700.1 360.1 687.7 377.8 691 396.3 694.2 414.9 711.9 427.3 730.4 424 785.9 414.3 846.1 424.6 886.1 451.1 911 467.7 919 486.3 919 500.5 919 514.6 911 533.2 886.1 549.8L886 549.9C846.5 576.3 787.1 586.6 731.6 577.3 713 574.2 695.4 586.7 692.3 605.3 689.2 623.8 701.7 641.4 720.3 644.5 789.2 656.1 867 644.6 923.9 606.5 963.1 580.4 987.2 542.6 987.2 500.5 987.2 458.3 963.1 420.5 923.9 394.4L923.8 394.3ZM268.2 424C212.8 414.3 152.5 424.6 112.5 451.1 87.6 467.7 79.7 486.3 79.7 500.5 79.7 514.6 87.6 533.2 112.5 549.8L112.6 549.9C152.1 576.3 211.5 586.6 267.1 577.3 285.6 574.2 303.2 586.7 306.3 605.3 309.5 623.8 296.9 641.4 278.4 644.5 209.4 656.1 131.6 644.6 74.7 606.5 35.6 580.4 11.5 542.6 11.5 500.5 11.5 458.3 35.6 420.5 74.7 394.4L74.8 394.3C132.1 356.3 210.9 344.8 280 356.9 298.5 360.1 310.9 377.8 307.7 396.3 304.4 414.9 286.8 427.3 268.2 424ZM495.9 419.1C449.7 419.1 412.7 456.1 412.7 502.3 412.7 546.7 446.9 582.5 490.2 585.4 493.9 585 497.6 585 501.3 585.4 544.2 582.9 578.7 547 579.1 502.1 579 456.4 542 419.1 495.9 419.1ZM344.5 502.3C344.5 418.4 412.1 350.9 495.9 350.9 579.8 350.9 647.3 419 647.3 502.3V502.5H647.3C646.7 584.1 582.5 651.3 501 653.6 499.2 653.7 497.4 653.6 495.7 653.4 493.8 653.6 492 653.7 490.1 653.6 409.1 650.7 344.5 584.3 344.5 502.3ZM651.2 734.4C608.2 705.7 553.3 692.5 500.2 692.5 447 692.5 392 705.7 348.9 734.3L348.8 734.4C309.7 760.5 285.6 798.3 285.6 840.5 285.6 882.6 309.7 920.4 348.8 946.5 391.9 975.4 446.9 988.8 500 988.8 553.1 988.8 608.1 975.4 651.2 946.5 690.3 920.4 714.4 882.6 714.4 840.5 714.4 798.3 690.3 760.5 651.2 734.4ZM353.7 840.5C353.7 826.3 361.7 807.7 386.6 791.1 416.2 771.5 457.3 760.7 500.2 760.7 543.1 760.7 584 771.5 613.4 791.1 638.3 807.7 646.3 826.3 646.3 840.5 646.3 854.6 638.3 873.2 613.4 889.8L613.3 889.8C583.7 909.6 542.8 920.6 500 920.6 457.2 920.6 416.3 909.6 386.7 889.8L386.6 889.8C361.7 873.2 353.7 854.6 353.7 840.5Z",
"width": 1000 "width": 1000
}, },
"search": ["settings"] "search": ["players"]
}, },
{ {
"uid": "dd62c27b488715bc9c53b0d0eb62e70f", "uid": "dd62c27b488715bc9c53b0d0eb62e70f",

9
src/i18n/interfaces/common.interface.ts

@ -5,4 +5,13 @@ interface Validation {
export interface Common { export interface Common {
validate: Validation validate: Validation
shareMessage: string shareMessage: string
notFillPlayerTitle: string
notFillPlayerMessage: string
helpAlertTitle: string
helpAlertDesc: string
writeUsBtn: string
limitTitle: string
limitDesc: string
buyAfterBtn: string
no: string
} }

2
src/i18n/interfaces/custom-pack.interface.ts

@ -19,4 +19,6 @@ export interface CustomPack {
alertEmptyTitle: string alertEmptyTitle: string
alertEmptyTruthDesc: string alertEmptyTruthDesc: string
alertEmptyDaresDesc: string alertEmptyDaresDesc: string
addCustomTruth: string
addCustomDare: string
} }

1
src/i18n/interfaces/page-titles.interface.ts

@ -2,4 +2,5 @@ export interface PageTitles {
settings: string, settings: string,
privacy: string, privacy: string,
terms: string, terms: string,
players: string
} }

12
src/i18n/locales/en/common.translation.ts

@ -8,4 +8,16 @@ const Validation = {
export const common: Common = { export const common: Common = {
validate: Validation, validate: Validation,
shareMessage: 'Share this app with your friends', shareMessage: 'Share this app with your friends',
notFillPlayerTitle: 'Oops',
notFillPlayerMessage:
'It seems that you did not fill in all the players name. Please fill it!',
helpAlertTitle: 'Well!',
helpAlertDesc:
'We will consider your question and give you an answer as soon as possible.',
writeUsBtn: 'Send',
limitTitle: 'Limit exhausted',
limitDesc:
'You have reached the limit of questions for this set. You need the full version to continue, but you can use “Under18” and “Light” packages. They are always open for you.',
buyAfterBtn: 'Buy',
no: 'Back',
} }

18
src/i18n/locales/en/custom-pack.translation.ts

@ -1,4 +1,4 @@
import { CustomPack } from "~i18n/interfaces/custom-pack.interface"; import { CustomPack } from '~i18n/interfaces/custom-pack.interface'
export const customPack: CustomPack = { export const customPack: CustomPack = {
label: 'Custom package', label: 'Custom package',
@ -7,21 +7,23 @@ export const customPack: CustomPack = {
'Create your own custom pack with questions and task. It all depends on your imagination!', 'Create your own custom pack with questions and task. It all depends on your imagination!',
editor: 'Editor', editor: 'Editor',
placeholder: 'Write here...', placeholder: 'Write here...',
addTruth: 'Add a truth', addTruth: 'Add a question',
addDare: 'Add a dare', addDare: 'Add a dare',
viewTruths: 'View truths', viewTruths: 'View questions',
viewDares: 'View dares', viewDares: 'View dares',
alertCreateTitle: 'Gratefully!', alertCreateTitle: 'Gratefully! 🎉',
alertCreateDesc: 'You can play your custom package now!', alertCreateDesc: 'You can play your custom package now!',
alertSaveTitle: 'You have unsaved changes', alertSaveTitle: 'You have unsaved changes.',
alertSaveDesc: 'Save changes?', alertSaveDesc: 'Save changes?',
alertSaveNo: 'No', alertSaveNo: 'No',
alertSaveYes: 'Save', alertSaveYes: 'Save',
alertEmptyTitle: 'Oops!', alertEmptyTitle: 'Oops! 👀',
alertEmptyTruthDesc: alertEmptyTruthDesc:
'Your truths list is empty. You need have at least 1 truth', 'Your questions list is empty. You need have at least 1 question.',
alertEmptyDaresDesc: alertEmptyDaresDesc:
'Your dares list is empty. You need have at least 1 dare', 'Your dares list is empty. You need have at least 1 dare.',
editorBtn: 'Tasks and questions editor', editorBtn: 'Tasks and questions editor',
play: 'Play', play: 'Play',
addCustomTruth: 'Add this question to Custom pack?',
addCustomDare: 'Add this question to Custom pack?',
} }

2
src/i18n/locales/en/onBoardingButton.translation.ts

@ -1,6 +1,6 @@
export const buttonsTranslation = { export const buttonsTranslation = {
skip: 'Skip', skip: 'Skip',
priceButton: 'Open now / $4.99', priceButton: 'Open now / $1.99',
later: 'Later', later: 'Later',
truth: '-TRUTH-', truth: '-TRUTH-',
random: 'RANDOM CHANCE', random: 'RANDOM CHANCE',

1
src/i18n/locales/en/page-title.translation.ts

@ -4,4 +4,5 @@ export const pageTitles = {
privacy: 'Privacy Policy', privacy: 'Privacy Policy',
terms: 'Terms and conditions', terms: 'Terms and conditions',
writeToUs: 'Write to us', writeToUs: 'Write to us',
players: 'Players'
} }

4
src/i18n/locales/en/steps.translation.ts

@ -8,11 +8,11 @@ export const onBoardingTranslation: OnBoardingLocale.OnboardingSteps = {
step2: { step2: {
title: 'Relax and enjoy \n the game!', title: 'Relax and enjoy \n the game!',
description: description:
'This game features 5 levels of "spiciness",\n some of which are divided into games for a \n couple or a company. All you have to do is \n add players and you can start playing.\n P.S. You can always create your own \n questions and tasks.', 'This game features 3 levels of "spiciness",\n some of which are divided into games for a \n couple or a company. All you have to do is \n add players and you can start playing.\n P.S. You can always create your own \n questions and tasks.',
}, },
step3: { step3: {
title: 'Premium version!', title: 'Premium version!',
description: description:
'Provides unlimited access to Hard and \n Extreme packages. Enjoy intriguing questions \n and exciting action.', 'Provides unlimited access to Crazy package. Enjoy intriguing questions \n and exciting action.',
}, },
} }

2
src/i18n/locales/hi/onBoardingButton.translation.ts

@ -1,6 +1,6 @@
export const buttonsTranslation = { export const buttonsTranslation = {
skip: 'जनक', skip: 'जनक',
priceButton: 'जनक/ $4.99', priceButton: 'जनक/ $1.99',
later: 'जनक', later: 'जनक',
truth: '-सच-', truth: '-सच-',
random: 'यिक म', random: 'यिक म',

9
src/i18n/locales/ua/common.translation.ts

@ -8,4 +8,13 @@ const Validation = {
export const common: Common = { export const common: Common = {
validate: Validation, validate: Validation,
shareMessage: 'Поділіться цим додатком зі своїми друзями', shareMessage: 'Поділіться цим додатком зі своїми друзями',
notFillPlayerTitle: 'Ой',
notFillPlayerMessage: 'Якесь поле не заповнене. Перевір будь ласка!',
helpAlertTitle: 'Добре!',
helpAlertDesc: 'Ми розглянемо питання і якнайшвидше дамо відповідь.',
writeUsBtn: 'Відправити',
limitTitle: 'Ліміт вичерпано',
limitDesc: 'Ліміт питань для пакету "Crazy" вичерпано. Щоб продовжити, потрібна повна версія. Але ти можеш використовувати пакети «До 18» та «Легкий». Вони завжди відкриті для тебе.',
buyAfterBtn: 'До покупок',
no: 'Назад'
} }

18
src/i18n/locales/ua/custom-pack.translation.ts

@ -1,27 +1,29 @@
import { CustomPack } from '~i18n/interfaces/custom-pack.interface' import { CustomPack } from '~i18n/interfaces/custom-pack.interface'
export const customPack: CustomPack = { export const customPack: CustomPack = {
label: 'Власний пакет', label: 'Мій пакет',
title: 'Створити власний пакет', title: 'Створити свій пакет',
description: description:
'Створіть свій власний пакет з правд та дій. Все залежить від вашої уяви!', 'Створи свій пакет з питань та дій. Все залежить від твоєї уяви!',
editor: 'Редактор', editor: 'Редактор',
placeholder: 'Пишіть тут...', placeholder: 'Писати тут...',
addTruth: 'Додати питання', addTruth: 'Додати питання',
addDare: 'Додати дію', addDare: 'Додати дію',
viewTruths: 'Питання', viewTruths: 'Питання',
viewDares: 'Дії', viewDares: 'Дії',
alertCreateTitle: 'Чудово! 🎉', alertCreateTitle: 'Чудово! 🎉',
alertCreateDesc: 'Зіграйте прямо зараз!', alertCreateDesc: 'Зіграй прямо зараз!',
alertSaveTitle: 'Ви маєте незбережені зміни', alertSaveTitle: 'У тебе незбережені зміни',
alertSaveDesc: 'Зберегти зміни?', alertSaveDesc: 'Зберегти зміни?',
alertSaveNo: 'Ні', alertSaveNo: 'Ні',
alertSaveYes: 'Так', alertSaveYes: 'Так',
alertEmptyTitle: 'Ой! 👀', alertEmptyTitle: 'Ой! 👀',
alertEmptyTruthDesc: alertEmptyTruthDesc:
'Ваш список правд порожній. Вам потрібно мати хоча б 1 правду', 'Твій список питань порожній. Потрібно мати хоча б 1 питання.',
alertEmptyDaresDesc: alertEmptyDaresDesc:
'Ваш список викликів порожній. Вам потрібно мати хоча б 1 виклик', 'Твій список дій порожній. Потрібно мати хоча б 1 дії.',
editorBtn: 'Редактор правд та дій', editorBtn: 'Редактор правд та дій',
play: 'Грати', play: 'Грати',
addCustomTruth: 'Додати це питання до твого пакету?',
addCustomDare: 'Додати цю дію до твого пакету?',
} }

2
src/i18n/locales/ua/onBoardingButton.translation.ts

@ -1,6 +1,6 @@
export const buttonsTranslation = { export const buttonsTranslation = {
skip: 'Далі', skip: 'Далі',
priceButton: 'Придбати за / $4.99', priceButton: 'Придбати за / $1.99',
later: 'Пізніше', later: 'Пізніше',
truth: '-ПРАВДА-', truth: '-ПРАВДА-',
random: 'ВИПАДКОВО', random: 'ВИПАДКОВО',

1
src/i18n/locales/ua/page-title.translation.ts

@ -4,4 +4,5 @@ export const pageTitles = {
privacy: 'Політика \n конфіденційності', privacy: 'Політика \n конфіденційності',
terms: 'Правила та умови', terms: 'Правила та умови',
writeToUs: 'Напишіть нам', writeToUs: 'Напишіть нам',
players: 'Гравці',
} }

2
src/i18n/locales/ua/purchases.translation.ts

@ -5,7 +5,7 @@ export const purchases: PurchasesTranslate = {
descSuccess: 'Тепер зіграйте з друзями! Насолоджуйтеся грою 😊', descSuccess: 'Тепер зіграйте з друзями! Насолоджуйтеся грою 😊',
alertError: 'Упс, щось не так 😢', alertError: 'Упс, щось не так 😢',
descError: descError:
'Виникла помилка обробки вашої покупки. Будь ласка, спробуйте пізніше.', 'Виникла помилка при обробці покупки. Будь ласка, спробуйте пізніше.',
allPackage: 'Відкрити всі пакети', allPackage: 'Відкрити всі пакети',
crazy: 'Відкрити пакет "Божевільний"', crazy: 'Відкрити пакет "Божевільний"',
under18: 'Відкрити пакет "До 18"', under18: 'Відкрити пакет "До 18"',

2
src/i18n/locales/ua/settings.translation.ts

@ -6,7 +6,7 @@ export const settingTranslation: SettingLocale.Core = {
notifications: 'Сповіщення', notifications: 'Сповіщення',
write: 'Напишіть нам', write: 'Напишіть нам',
rate: 'Оцініть нас', rate: 'Оцініть нас',
share: 'Поділитися програмою', share: 'Поділитися додатком',
policy: 'Політика конфіденційності', policy: 'Політика конфіденційності',
label: 'Чим ми можемо допомогти?', label: 'Чим ми можемо допомогти?',
} }

35
src/i18n/locales/ua/step.translation.ts

@ -1,21 +1,18 @@
export const onBoardingTranslationUa = { export const onBoardingTranslationUa = {
step1: { step1: {
title: 'Ласкаво просимо!', title: 'Ласкаво просимо!',
description: description:
'Дякуємо за завантаження. Тепер ви \n в найкращій грі для компанії або \n пограти з коханою людиною', 'Дякуємо за завантаження. Тепер ти \n в найкращій грі для компанії або \n пограти з коханою людиною',
}, },
step2: {
title: 'Розслабтеся та насолоджуйтеся грою',
description:
'У цій грі є 5 рівнів "пікантності", деякі з яких розділені на ігри для пари або компанії. Все, що вам потрібно зробити, це додати гравців, і ви можете почати грати.\n P.S. Ви завжди можете створити власні питання та завдання',
},
step3: {
title: 'Преміум версія!',
description:
'Надає необмежений доступ до пакетів Hard та режиму Extreme \nНасолоджуйтеся інтригуючими запитаннями та захоплюючими діями',
},
};
step2: {
title: 'Розслабся та насолоджуйся грою',
description:
'У цій грі є 3 рівня "пікантності". Все, що потрібно - це додати гравців.\n P.S. Ти завжди можеш створити власні питання та завдання',
},
step3: {
title: 'Преміум версія!',
description:
'Надає необмежений доступ до пакету "Сrazy". \nНасолоджуйся інтригуючими запитаннями та захоплюючими діями',
},
}

2
src/module/common/components/buttons/button-primary.component.tsx

@ -17,7 +17,7 @@ type ButtonStyleMod = 'filled' | 'outline' | 'danger'
interface IButtonPrimaryProps { interface IButtonPrimaryProps {
mod?: ButtonStyleMod mod?: ButtonStyleMod
style?: ViewStyle style?: ViewStyle | ViewStyle[]
onPress: () => void onPress: () => void
isLoading?: boolean isLoading?: boolean

1
src/module/common/components/form/form-controll-wrap.component.tsx

@ -44,7 +44,6 @@ const styles = StyleSheet.create({
labelWrap: { labelWrap: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
marginBottom: 5,
}, },
label: { label: {
color: colors.secondaryText, color: colors.secondaryText,

13
src/module/common/components/form/form-text-controll.component.tsx

@ -19,7 +19,9 @@ interface FormTextControllProps {
label?: string label?: string
error?: string error?: string
renderClearPostfix?: () => React.JSX.Element renderPostfix?: () => React.JSX.Element
renderPrefix?: () => React.JSX.Element
subtext?: string subtext?: string
inputStyle?: ViewStyle inputStyle?: ViewStyle
@ -35,7 +37,8 @@ export const FormTextControll: FC<FormTextControllProps> = ({
label, label,
error, error,
renderClearPostfix, renderPostfix,
renderPrefix,
inputStyle, inputStyle,
style, style,
@ -43,6 +46,7 @@ export const FormTextControll: FC<FormTextControllProps> = ({
return ( return (
<FormControllWrap label={label} error={error} style={style}> <FormControllWrap label={label} error={error} style={style}>
<View style={styles.inputContainer}> <View style={styles.inputContainer}>
{renderPrefix && renderPrefix()}
<TextInput <TextInput
style={[ style={[
styles.input, styles.input,
@ -54,7 +58,7 @@ export const FormTextControll: FC<FormTextControllProps> = ({
placeholderTextColor="#A0A3BD" placeholderTextColor="#A0A3BD"
{...inputProps} {...inputProps}
/> />
{renderClearPostfix && renderClearPostfix()} {renderPostfix && renderPostfix()}
</View> </View>
</FormControllWrap> </FormControllWrap>
) )
@ -65,7 +69,7 @@ const styles = StyleSheet.create({
borderColor: '#FB5450', borderColor: '#FB5450',
}, },
inputContainer: { inputContainer: {
paddingRight: 1, flexDirection: 'row',
}, },
input: { input: {
borderColor: colors.secondaryText, borderColor: colors.secondaryText,
@ -76,6 +80,7 @@ const styles = StyleSheet.create({
color: colors.textPrimary, color: colors.textPrimary,
fontFamily: Font.Roboto400, fontFamily: Font.Roboto400,
fontSize: 16, fontSize: 16,
width: '100%',
}, },
inputActive: { inputActive: {
borderColor: '#FB5450', borderColor: '#FB5450',

41
src/module/common/components/header/header.component.tsx

@ -32,10 +32,10 @@ export const Header: FC<IProps> = ({
return ( return (
<View style={styles.header}> <View style={styles.header}>
<View style={styles.button}> <View style={styles.buttonView}>
{leftIcon && ( {leftIcon && (
<TouchableOpacity <TouchableOpacity
style={styles.button} style={styles.btn}
onPress={onPressLeft || goBack}> onPress={onPressLeft || goBack}>
<Icon <Icon
name={leftIcon} name={leftIcon}
@ -46,19 +46,19 @@ export const Header: FC<IProps> = ({
)} )}
</View> </View>
<View <View style={styles.wrap}>
style={[ <View
styles.titleContainer, style={[
gamer && { backgroundColor: colors.darkPurple }, styles.titleContainer,
]}> gamer && { backgroundColor: colors.darkPurple },
<Txt style={styles.title}>{title}</Txt> ]}>
<Txt style={styles.title}>{title}</Txt>
</View>
</View> </View>
<View style={styles.button}> <View style={styles.buttonView}>
{rightIcon && ( {rightIcon && (
<TouchableOpacity <TouchableOpacity style={styles.btn} onPress={onPressRight}>
style={styles.button}
onPress={onPressRight}>
<Icon <Icon
name={rightIcon} name={rightIcon}
size={24} size={24}
@ -77,7 +77,6 @@ const styles = StyleSheet.create({
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
justifyContent: 'space-between', justifyContent: 'space-between',
paddingHorizontal: 24,
}, },
title: { title: {
color: colors.turquoise, color: colors.turquoise,
@ -87,13 +86,25 @@ const styles = StyleSheet.create({
}, },
titleContainer: { titleContainer: {
borderRadius: 60, borderRadius: 60,
minWidth: 130,
padding: 14, padding: 14,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
}, },
button: { wrap: {
position: 'absolute',
width: '100%',
left: 0,
right: 0,
top: 3,
justifyContent: 'center',
alignItems: 'center',
},
buttonView: {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
zIndex: 2,
},
btn: {
paddingHorizontal: 24,
}, },
}) })

2
src/module/common/hooks/index.ts

@ -1,5 +1,3 @@
export * from './use-nav.hook' export * from './use-nav.hook'
export * from './use-dispatch.hook'
export * from './use-events-listener.hook' export * from './use-events-listener.hook'
export * from './use-selector.hook'
export * from './use-form.hook' export * from './use-form.hook'

4
src/module/common/hooks/use-dispatch.hook.ts

@ -1,4 +0,0 @@
import { useDispatch } from 'react-redux'
import { AppDispatch } from '../../../store/store'
export const useAppDispatch = () => useDispatch<AppDispatch>()

5
src/module/common/hooks/use-selector.hook.ts

@ -1,5 +0,0 @@
import { useSelector } from 'react-redux'
import { TypedUseSelectorHook } from 'react-redux'
import { RootState } from '../../../store/store'
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

1
src/module/common/index.ts

@ -7,3 +7,4 @@ export * from './events'
export * from './tools' export * from './tools'
export * from './widgets' export * from './widgets'
export * from './svg-icons' export * from './svg-icons'
export * from './services';

746
src/module/common/questions-dares-list/questions-dares-list.ts

@ -0,0 +1,746 @@
export const under18 = [
{
id: 1,
isDare: false,
en: 'Tell about your first fight?',
ua: 'Розкажи про свою першу бійку?',
},
{
id: 2,
isDare: true,
en: 'Do your best dance moves for 20 seconds.',
ua: 'Покажи свої найкращі танцювальні рухи протягом 20 секунд.',
},
{
id: 3,
isDare: false,
en: 'Which superpower would you choose?',
ua: 'Яку б суперсилу ти обрав(ла)?',
},
{
id: 4,
isDare: true,
en: 'Take a funny selfie and share it with the any group.',
ua: 'Зроби веселе селфі та кинь його в якийсь чат.',
},
{
id: 5,
isDare: false,
en: 'What do you dream of doing by 18?',
ua: 'Що ти мрієш зробити до 18?',
},
{
id: 6,
isDare: true,
en: 'Tell a funny joke.',
ua: 'Розкажи смішний анекдот/прікол.',
},
{
id: 7,
isDare: false,
en: 'If you could visit any place in the world, where would you go?',
ua: 'Якщо б ти міг(могла) відвідати будь-яке місце у світі, куди б ти поїхав(ла)?',
},
{
id: 8,
isDare: true,
en: 'Make a scarf out of toilet paper and sit like that until the end of the game.',
ua: 'Зроби шарф з туалетного паперу і сиди так до кінця гри.',
},
{
id: 9,
isDare: false,
en: 'Name a song that you are uncomfortable listening to in front of others',
ua: 'Назви пісню, яку тобі некомфортно слухати при інших',
},
{
id: 10,
isDare: true,
en: "Write 'Where's my beer' to your president on the social network ",
ua: 'Напиши "Де моє пиво" своєму президентові в соціальній мережі',
},
{
id: 11,
isDare: false,
en: ' If you had to delete one person from your life permanently, who would it be and why?',
ua: 'Якщо б тобі довелося видалити одну особу зі свого життя назавжди, хто б це був і чому?',
},
{
id: 12,
isDare: true,
en: 'Call someone on video, be silent for 10 seconds and knock out',
ua: 'Подзвони комусь по відео мовчи 10 секунд і вибий',
},
{
id: 13,
isDare: false,
en: "What's the most disgusting thing you've ever tried?",
ua: 'Що найогидніше ти коли-небудь пробував(ла)?',
},
{
id: 14,
isDare: true,
en: 'Sing the chorus of any song loudly.',
ua: 'Голосно заспівай приспів будь-якої пісні.',
},
{
id: 15,
isDare: false,
en: 'You can travel through time. Where and why would you go?',
ua: 'Ти вмієш подорожувати в часі. Куди і чому б ти поїхав(ла)?',
},
{
id: 16,
isDare: true,
en: 'Imitate your favorite character for 20 seconds.',
ua: 'Імітуй свого улюбленого персонажа протягом 20 секунд.',
},
{
id: 17,
isDare: false,
en: 'You can kiss any celebrity. Who would it be and why?',
ua: 'Ти можеш поцілувати будь-яку знаменитість. Хто б це був і чому?',
},
{
id: 18,
isDare: true,
en: 'Send a heartfelt message to the fifth person in your contact list, expressing gratitude for something',
ua: "Відправ сердечне повідомлення п'ятій людині у своєму списку контактів, висловлюючи вдячність за щось",
},
{
id: 19,
isDare: false,
en: 'If you had a pet dragon, what would you name it?',
ua: 'Якщо б у тебе був домашній дракон, як ти б його назвав(ла)?',
},
{
id: 20,
isDare: true,
en: 'Show your scary photo.',
ua: 'Покажи своє страшне фото.',
},
{
id: 21,
isDare: false,
en: 'What is your most embarrassing moment from childhood?',
ua: "Який твій найбільш сором'язливий момент з дитинства?",
},
{
id: 22,
isDare: true,
en: 'Dance like nobody is watching for 10 seconds.',
ua: 'Танцюй так, наче тебе ніхто не бачить, протягом 10 секунд.',
},
{
id: 23,
isDare: false,
en: 'If you could expose one secret about someone in this room, what would it be?',
ua: 'Якби тобі довелося викрити один секрет про когось у цій кімнаті, який би це був?',
},
{
id: 24,
isDare: true,
en: 'Write an message with some hint to the person you like.',
ua: 'Напишіть повідомлення з натяком людині, яка вам подобається.',
},
{
id: 25,
isDare: false,
en: "What's the wildest thing you've done when you thought no one was watching?",
ua: 'Яка найбільш дика річ, яку ти робив, коли думав, що тебе ніхто не бачить?',
},
{
id: 26,
isDare: true,
en: 'Take a silly selfie and post it on your social media.',
ua: 'Зроби дурницю селфі і опублікуй його у своїй соціальній мережі.',
},
{
id: 27,
isDare: false,
en: 'If you could swap lives with someone for a day, who would it be?',
ua: 'Якщо б ти міг(могла) помінятися життям з кимось на один день, хто б це був?',
},
{
id: 28,
isDare: true,
en: 'Take a screenshot of your recommendations on Instagram.',
ua: 'Зроби скріншот своїх рекомендацій в інстаграмі.',
},
{
id: 29,
isDare: false,
en: 'Tell a fact about yourself that none of the participants knows.',
ua: 'Розкажи про себе факт, який не знає ніхто з учасників.',
},
{
id: 30,
isDare: true,
en: 'Call a friend and wish him a happy birthday.',
ua: 'Подзвони другові(подрузі) і привітай з днем народження.',
},
{
id: 31,
isDare: false,
en: "If you had the power to erase one person's memory of you, who would it be and why?",
ua: "Якби у тебе була сила стерти пам'ять одній людини про тебе, хто б це був і чому?",
},
{
id: 32,
isDare: true,
en: 'Share a funny photo from your childhood with the participants.',
ua: 'Поділись з учасниками смішною фоткою свого дитинства.',
},
{
id: 33,
isDare: false,
en: "What is the most brave thing you've ever done?",
ua: 'Яка найсміливіша річ, яку ти коли-небудь робив(ла)?',
},
{
id: 34,
isDare: true,
en: "Change your phone's language settings to Chinese and use it that way for the rest of the day.",
ua: 'Зміни мовні налаштування телефону на китайську мову, і використовуй його так до кінця дня.',
},
{
id: 35,
isDare: false,
en: 'That you would eat one thing all your life?',
ua: 'Що б ти їв(ла) щось одне все життя?',
},
{
id: 36,
isDare: true,
en: 'Go live with a funny mask.',
ua: 'Почни трансляцію у прямому ефірі з смішною маскою.',
},
{
id: 37,
isDare: false,
en: 'What is the most useless talent you have?',
ua: 'Який найбільш безглуздий талант у тебе є?',
},
{
id: 38,
isDare: true,
en: 'Picture yourself as a dove.',
ua: 'Зобразити себе у вигляді голуба.',
},
{
id: 39,
isDare: false,
en: 'You can choose a slave from among the participants. Who would it be?',
ua: 'Ти можеш вибрати собі раба з учасників. Хто б це був?',
},
{
id: 40,
isDare: true,
en: 'Do your best dance moves for the next minute.',
ua: 'Станцюй свій найкрутіший танець протягом 20 секунд під музику.',
},
{
id: 41,
isDare: false,
en: 'What’s the most unusual job you can think of?',
ua: 'Найдурніша робота, яку б ти робив(ла) за хороші гроші?',
},
]
export const light = [
{
id: 1,
isDare: false,
en: 'Tell me about a deception that benefited you.',
ua: 'Розкажи про обман, який приніс тобі користь.',
},
{
id: 2,
isDare: true,
en: 'Одягни на вуха носки і сиди так 3 раунда.',
ua: 'Put socks on your ears and sit like that for 3 rounds.',
},
{
id: 3,
isDare: false,
en: 'What is the most unethical thing you have done in public?',
ua: 'Яка найбільш неетична річ, яку ти зробив(ла) на людях?',
},
{
id: 4,
isDare: true,
en: 'Take a funny selfie and post it on your social media.',
ua: 'Зроби смішне селфі і запости його у одну з соц. мереж.',
},
{
id: 5,
isDare: false,
en: 'Найекстремальніше, що ти робив(ла), щоб комусь сподобатись?',
ua: "What's the most extreme thing you've done to please someone?",
},
{
id: 6,
isDare: true,
en: 'Dance a funny and energetic dance to sad and slow music.',
ua: 'Танцюй смішний та енергічний танець під сумну та повільну музику.',
},
{
id: 7,
isDare: false,
en: 'If you could be invisible for a day, what would you do?',
ua: 'Якщо б ви могли бути невидимими на один день, Що б ти зробив(ла), якб?',
},
{
id: 8,
isDare: true,
en: 'The participant to your right must draw you any picture with a pen anywhere.',
ua: 'Учасник справа від тебе має намалювати тобі будь який малюнок ручкою в любому місці.',
},
{
id: 9,
isDare: false,
en: 'What is the weirdest talent you have?',
ua: 'Що ти вмієш робити найдивніше?',
},
{
id: 10,
isDare: true,
en: `Change your relationship status to "It's complicated" and leave it for 24 hours.`,
ua: 'Зміни свій статус відносин на "Складно" і залиш його протягом 24 годин.',
},
{
id: 11,
isDare: false,
en: 'What’s the most unusual place you’ve ever visited?',
ua: 'Яке найстрашніше місце, в якому ти був(ла)',
},
{
id: 12,
isDare: true,
en: '"Write to your parents that you love them.',
ua: 'Напиши батькам, що ти їх любиш.',
},
{
id: 13,
isDare: false,
en: 'If you could time travel, which era would you visit and why?',
ua: 'Якщо б ти міг подорожувати в часі, яку епоху та місце ти б відвідав(ла) і чому?',
},
{
id: 14,
isDare: true,
en: 'Roar when others laugh. The desire is valid until you choose another action.',
ua: 'Каркай, коли інші сміються. Бажання дійсне поки не вибереш іншу дію.',
},
{
id: 15,
isDare: false,
en: 'Tell about your dumbest act.',
ua: 'Розкажи про свій найтупійший вчинок.',
},
{
id: 16,
isDare: true,
en: 'Show a photo of yourself in your underwear.',
ua: 'Покажи своє фото в нижній білизні.',
},
{
id: 17,
isDare: false,
en: 'What do you often look at on the Internet?',
ua: 'Про що ти часто дивишся в інтернеті?',
},
{
id: 18,
isDare: true,
en: 'Everyone has to give you a new hairstyle.',
ua: 'Всі мають зробити тобі нову зачіску.',
},
{
id: 19,
isDare: false,
en: 'What do you often look at on the Internet?',
ua: 'Про що ти часто дивишся в інтернеті?',
},
{
id: 20,
isDare: true,
en: 'Voice the emotions of your stomach when tomato juice and diesel get there.',
ua: 'Озвуч емоції свого шлунку, коли туди попадає томатний сік і дизель.',
},
{
id: 21,
isDare: false,
en: 'Tell the funniest story about how you threw up.',
ua: 'Розкажи про якусь ситуацію, яку ти бачив на власні очі.',
},
{
id: 22,
isDare: true,
en: 'You are a tarot reader. Give a forecast for the future to the participant opposite you.',
ua: 'Ти таролог. Дай прогноз на майбутне учаснику навпроти тебе.',
},
{
id: 23,
isDare: false,
en: 'Tell about your worst dream.',
ua: 'Розкажи про свій найгірший сон.',
},
{
id: 24,
isDare: true,
en: 'Stand on a chair and say your favorite Chinese-style toast.',
ua: 'Стань на стільчик та скажи любий тост у китайському стилі.',
},
{
id: 25,
isDare: false,
en: 'Describe your character in 5 words.',
ua: 'Опиши свій характер 5-ма словами.',
},
{
id: 26,
isDare: true,
en: 'Show your hobby with facial expressions and movements. Everyone must guess it. Whoever guessed should get a slap on the cheek.',
ua: 'Показати своє хобі мімікою і рухами. Всі повинні його вгадати. Хто вгадав, має отримати по щоці.',
},
{
id: 27,
isDare: false,
en: 'Have you ever followed someone?',
ua: 'Ти колись слідкував за кимось?',
},
{
id: 28,
isDare: true,
en: 'Tell about a time when you successfully took revenge on someone.',
ua: 'Розкажи про випадок, коли ти комусь успішно відімстив.',
},
{
id: 27,
isDare: false,
en: 'Tell about the channel that you immediately open when something new appears there.',
ua: 'Розкажи про канал, який ти одразу відкриваєш, коли там з являється щось нове.',
},
{
id: 28,
isDare: true,
en: 'Take any item and try to sell it to others, praising it.',
ua: 'Візьми будь-який предмет і спробуй продати іншим, нахвалюючи його.',
},
{
id: 29,
isDare: false,
en: 'Tell about the channel that you immediately open when something new appears there.',
ua: 'Розкажи про канал, який ти одразу відкриваєш, коли там з являється щось нове.',
},
{
id: 30,
isDare: true,
en: 'Lick your lips sexily and look at the participant across from you.',
ua: 'Сексуально оближ губи і подивись на учасника навпроти тебе.',
},
{
id: 31,
isDare: false,
en: 'Have you ever been dumped by a person you liked?',
ua: 'Тебе колись кидала людина, яка тобі подобалась?',
},
{
id: 32,
isDare: true,
en: 'Sit with an angry and sad face until the next round.',
ua: 'Сиди зі злою та сумною міною до наступного раунда.',
},
{
id: 33,
isDare: false,
en: 'Have you ever been dumped by a person you liked?',
ua: 'Тебе колись кидала людина, яка тобі подобалась?',
},
{
id: 34,
isDare: true,
en: 'Sit with an angry and sad face until the next round.',
ua: 'Сидіть зі злою та сумною міною до наступного раунда.',
},
{
id: 35,
isDare: false,
en: 'When was the last time you cried and why?',
ua: 'Коли ти востаннє плакав(ла) і чому?',
},
{
id: 36,
isDare: true,
en: 'Picture a popular person so that others will remember him.',
ua: 'Зобрази популярну людину, щоб інші її відгадали.',
},
{
id: 37,
isDare: false,
en: 'You are invited on a date. You really like this person. For what reasons can you not go on a date?',
ua: 'Тебе запрошують на побачення. Ця людина тобі дуже подобається. По яким причинам ти можеш не піти на побачення?',
},
{
id: 38,
isDare: true,
en: 'Picture a hen that suddenly laid an egg.',
ua: 'Зобрази курку, яка раптом знесла яєчко.',
},
{
id: 39,
isDare: false,
en: 'Tell the whole story of how you quarreled with someone.',
ua: 'Розкажи всю історію, як ти з кимось сварився(лась).',
},
{
id: 40,
isDare: true,
en: 'Ask your partner for advice on how to please a guy/girl as realistically as possible.',
ua: 'Максимально реалістично попроси у своєї половинки поради як сподобатись хлопцю/дівчині.',
},
]
export const crazy = [
{
id: 1,
isDare: false,
en: 'Would you sacrifice a loved one to earn 100 times more than you do now?',
ua: 'Ти б пожертував(ла) близькою людиною, щоб заробляти в 100 разів більше, ніж зараз?',
},
{
id: 2,
isDare: true,
en: 'Dance for the next 20 seconds with any song.',
ua: 'Танцюй протягом 20 секунд під музику.',
},
{
id: 3,
isDare: false,
en: "What's the most embarrassing thing you've Googled?",
ua: "Найсором'язливіше, що ти шукав в Google?",
},
{
id: 4,
isDare: true,
en: "Call a friend and sing 'Happy Birthday' to them, regardless of whether it's their birthday or not.",
ua: "Подзвони другові і заспівай 'З днем народження' незалежно від його дати народження.",
},
{
id: 5,
isDare: false,
en: "Have you ever intentionally ruined someone else's relationship, and if so, why?",
ua: 'Ти коли-небудь умисно руйнував відносини інших людей, і якщо так, чому?',
},
{
id: 6,
isDare: true,
en: 'Say "Koo-koo" to the player on your right after your turn is over.',
ua: 'Скажи "Ку-ку" учаснику справа від тебе після кожного завершення твого ходу.',
},
{
id: 7,
isDare: true,
en: "Record a dramatic monologue confessing to a fake crime and send it to a friend without telling them it's a joke.",
ua: 'Запиши драматичний монолог, визнаючись у фіктивному злочині, і відправ його другові, не вказавши, що це жарт.',
},
{
id: 8,
isDare: false,
en: 'How, why and whom you cruelly offended?',
ua: 'Як, чому і кого ти жорстоко образив?',
},
{
id: 9,
isDare: true,
en: "Send a text to your crush confessing your feelings (even if it's just for fun).",
ua: 'Напиши в особисті 10-му своєму підписнику "В мене погані новини для тебе" і не відповідай 24 години.',
},
{
id: 10,
isDare: false,
en: 'Did you cheat on someone? If so, does anyone know about it?',
ua: 'Ти комусь зраджував(ла)? Якщо так, чи знає хтось про це?',
},
{
id: 11,
isDare: true,
en: 'Wrap your socks around with the participant on the left to greet you.',
ua: 'Обіняйся носками з учасником зліва віт тебе.',
},
{
id: 12,
isDare: false,
en: 'Є людина, яку ти ненавидиш, але вона про це не знає?',
ua: "Is there a person you hate, but they don't know it?",
},
{
id: 13,
isDare: true,
en: 'Grunt every 30 seconds until the end of the game.',
ua: 'Хрюкай до кінця гри кожні 30 секунд.',
},
{
id: 14,
isDare: false,
en: "What's the most rebellious thing you did as a teenager?",
ua: 'Що найбільш хуліганське ти зробив(ла) в дитинстві?',
},
{
id: 15,
isDare: true,
en: 'Create a silly rap about the person to your right.',
ua: 'Заспівай дурний реп про особу справа від тебе.',
},
{
id: 16,
isDare: false,
en: 'Do you have a romantic or sexual fantasy about one of the participants?',
ua: 'Моєш романтичну чи сексуальну фантазію про когось з учасників?',
},
{
id: 17,
isDare: true,
en: 'Act like a certain animal until your next turn. Others have to guess the animal.',
ua: 'Ведіть себе як собака до свого наступного ходу.',
},
{
id: 18,
isDare: false,
en: 'You became invisible for a day. What will you do?',
ua: 'Ти невидимка на один день. Що будеш зробили?',
},
{
id: 19,
isDare: true,
en: 'Send a strange sound to the third person on your social media friends list.',
ua: 'Відправ дивний звук третій людині, на яку ти підписаний(на)',
},
{
id: 20,
isDare: false,
en: 'Picture your dream job.',
ua: 'Зобрази роботи мрії.',
},
{
id: 21,
isDare: true,
en: 'Post something embarrassing on your social media for the next 30 minutes.',
ua: 'Добав в сторіз щось сором’язливе на 1 хв.',
},
{
id: 22,
isDare: false,
en: 'What’s the most embarrassing thing you’ve said in the heat of the moment?',
ua: 'Що ти "ляпав(ла)" не те в пориві емоцій?',
},
{
id: 23,
isDare: true,
en: 'Sing a song loudly and out of tune.',
ua: 'Співай що завгодно наступні 10 секунд.',
},
{
id: 24,
isDare: false,
en: "There were times when you were hinted at sex, but you didn't understand the hint?",
ua: 'Були моменти, коли тобі натякали на секс, али ти не зрозумів(ла) натяк?',
},
{
id: 25,
isDare: true,
en: 'Take a goofy selfie and set it as your profile picture for the next hour.',
ua: 'Зроби невдале селфі і постав на аву на 1 годину.',
},
{
id: 26,
isDare: false,
en: 'Was there a time when you wanted sex and were refused?',
ua: 'Чи був момент, коли ти хотів(ла) сексу, а тобі не дали?',
},
{
id: 27,
isDare: true,
en: 'Send a message "I want it, and you?" 5th in your contact list.',
ua: 'Відправ повідомлення "Я хочу це, а ти?" 5-му в своєму списку контактів.',
},
{
id: 28,
isDare: false,
en: 'Would you go naked for a week for 100K hryvnias?',
ua: 'Ти б ходив ходив(ла) на протязі тижня голим(голою) за 100К гривень?',
},
{
id: 29,
isDare: true,
en: 'Take a selfie with a taxi driver, bus driver, cashier or a random passerby. Send the proof in your chat or group later.',
ua: 'Зроби селфі з таксистом, водієм маршрутки, касиркою або з випадковим перехожим. Потім покажеш доказ.',
},
{
id: 30,
isDare: false,
en: 'What is the most unethical thing you have seen in your life?',
ua: 'Назви найбільш неетична річ, яку ти бачив(ла) в своєму житті.',
},
{
id: 31,
isDare: true,
en: 'Add to any social media something that makes you feel ashamed for 10 minutes',
ua: 'Добав в любу соц. мережу щось, що викликає в тобі сором на 10 хв.',
},
{
id: 32,
isDare: false,
en: 'Was there a one-night stand? If so, how was it?',
ua: 'Був роман на одну ніч? Якщо так, то як це було?',
},
{
id: 33,
isDare: false,
en: 'Have you ever been punched in the face?',
ua: 'Ти колись отримував(ла) в лице?',
},
{
id: 34,
isDare: false,
en: 'When was the last time you shaved your anus?',
ua: 'Коли ти останній раз брив(ла) в ділянці анального отвору?',
},
{
id: 35,
isDare: true,
en: 'Fulfill the wish made by the youngest participant.',
ua: 'Виконай бажання, яке тобі загадає наймолодший учасник.',
},
{
id: 36,
isDare: false,
en: 'Tell about the strangest act that a person has done in a drunken state in your memory.',
ua: "Розкажи найдивніший вчинок, який зробила людина в нетверезому стані на твоїй пам'яті.",
},
{
id: 37,
isDare: true,
en: 'Go live with a funny mask.',
ua: 'Почни трансляцію у прямому ефірі з смішною маскою.',
},
{
id: 38,
isDare: false,
en: 'Now you can be asked any one question.',
ua: 'Зараз тобі можуть задати любе одне питання.',
},
{
id: 39,
isDare: true,
en: 'Roar when others laugh. The desire is valid until you choose another action.',
ua: 'Каркай, коли інші сміються. Бажання дійсне поки не вибереш іншу дію.',
},
{
id: 40,
isDare: false,
en: 'Name an unusual place you had sex.',
ua: 'Назви незвичне місце, в якому у тебе був секс.',
},
]

1
src/module/common/services/index.ts

@ -0,0 +1 @@
export * from './storage.service';

34
src/module/common/services/storage.service.ts

@ -0,0 +1,34 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { StorageKey } from '../typing'
export class StorageService {
constructor() {
this.init()
}
private init() {}
public async get(key: StorageKey) {
try {
const encode = await AsyncStorage.getItem(key)
if (encode) {
return JSON.parse(encode)
} else {
return null
}
} catch (error) {
console.error('error get from async storage', error)
}
}
public async set(key: StorageKey, data: any) {
try {
const encode = JSON.stringify(data)
await AsyncStorage.setItem(key, encode)
} catch (error) {
console.error('error set to async storage', error)
}
}
}
export const storageService = new StorageService()

4
src/module/common/typing/enums/choice-type.enum.ts

@ -0,0 +1,4 @@
export enum ChoiceType {
Truth = 'question',
Dare = 'dare',
}

2
src/module/common/typing/enums/type-custom.enum.ts → src/module/common/typing/enums/custom-type.enum.ts

@ -1,4 +1,4 @@
export enum TypeCustom { export enum CustomType {
Questions = 'questions', Questions = 'questions',
Dares = 'dares', Dares = 'dares',
} }

5
src/module/common/typing/enums/guest-route-keys.enum.ts

@ -0,0 +1,5 @@
export enum GuestRouteKey {
Onboarding = 'Onboarding',
LanguageSelect = 'LanguageSelect',
Loading = 'Loading',
}

11
src/module/common/typing/enums/index.ts

@ -1,6 +1,11 @@
export * from './route-keys.enum' export * from './guest-route-keys.enum'
export * from './fonts.enum' export * from './fonts.enum'
export * from './storage-key.enum' export * from './storage-key.enum'
export * from './language.enum' export * from './language.enum'
export * from './products.enum'; export * from './products.enum'
export * from './type-custom.enum'; export * from './custom-type.enum'
export * from './guest-route-keys.enum'
export * from './nav-group.enum'
export * from './user-route-keys.enum'
export * from './package-type.enum'
export * from './choice-type.enum';

4
src/module/common/typing/enums/nav-group.enum.ts

@ -0,0 +1,4 @@
export enum NavGroup {
User = 'u',
Guest = 'g'
}

6
src/module/common/typing/enums/package-type.enum.ts

@ -0,0 +1,6 @@
export enum PackageType {
Under18 = 'under18',
Light = 'light',
Crazy = 'crazy',
Custom = 'custom',
}

2
src/module/common/typing/enums/products.enum.ts

@ -1,5 +1,3 @@
export enum ProductsEnum { export enum ProductsEnum {
All = 'ALL',
Under18 = 'un18',
Crazy = 'Crz', Crazy = 'Crz',
} }

8
src/module/common/typing/enums/storage-key.enum.ts

@ -1,7 +1,11 @@
export enum StorageKey { export enum StorageKey {
OnBoarding = 'ONBOARDING_END', FinishOnBoarding = 'FinishOnBoarding',
Language = 'LANG_SELECTED', Language = 'Language',
Purchases = 'Purchases', Purchases = 'Purchases',
Products = 'Products', Products = 'Products',
CustomPackage = 'CustomPackage', CustomPackage = 'CustomPackage',
ShuffleCustomPackage = 'ShuffleCustomPackage',
Players = 'Players',
LimitForCrazy = 'limit',
SavedSteps = 'SavedSteps',
} }

6
src/module/common/typing/enums/route-keys.enum.ts → src/module/common/typing/enums/user-route-keys.enum.ts

@ -1,8 +1,6 @@
export enum RouteKey { export enum UserRouteKey {
Onboarding = 'Onboarding',
LanguageSelect = 'LanguageSelect',
Game = 'Game', Game = 'Game',
Loading = 'Loading', Players = 'Players',
Packages = 'Packages', Packages = 'Packages',
TruthOrDare = 'TruthOrDare', TruthOrDare = 'TruthOrDare',
CustomPackage = 'CustomPackage', CustomPackage = 'CustomPackage',

14
src/module/common/typing/interfaces/game-item.ts

@ -1,9 +1,9 @@
import { Language } from "../enums"; import { Language } from '../enums'
export interface GameItem { export interface GameItem {
id: number; id: number
isDare: boolean; isDare: boolean
en: Language; en: Language
ua: Language; ua: Language
hi: Language; hi?: Language
} }

1
src/module/custom-package/animation/index.ts

@ -0,0 +1 @@
export * from './use-animation-block.hook';

53
src/module/custom-package/animation/use-animation-block.hook.tsx

@ -0,0 +1,53 @@
import { useEffect, useRef } from 'react'
import { Animated } from 'react-native'
export const useAnimationBlock = (onDelete: any) => {
const deleteBlockAnim = useRef(new Animated.Value(0)).current
const viewBlockAnim = useRef(new Animated.Value(0)).current
const onPressDelete = () => {
Animated.timing(deleteBlockAnim, {
toValue: 1,
duration: 200,
useNativeDriver: true,
}).start(() => deleteBlockAnim.setValue(0))
setTimeout(onDelete, 200)
}
useEffect(() => {
Animated.timing(viewBlockAnim, {
toValue: 1,
duration: 0,
useNativeDriver: true,
}).start()
}, [])
const animStyle = {
transform: [
{
translateX: deleteBlockAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, 400],
}),
},
{
translateY: viewBlockAnim.interpolate({
inputRange: [0, 1],
outputRange: [-50, 0],
}),
},
],
opacity:
viewBlockAnim ||
deleteBlockAnim.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}),
}
return {
onPressDelete,
animStyle,
}
}

61
src/module/custom-package/atoms/custom-block.atom.tsx

@ -1,64 +1,19 @@
import React, { FC, useEffect, useRef } from 'react' import React, { FC } from 'react'
import { Animated, LayoutAnimation, StyleSheet } from 'react-native' import { Animated, StyleSheet } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler' import { TouchableOpacity } from 'react-native-gesture-handler'
import { Icon, Txt, colors } from '~module/common' import { Icon, Txt, colors } from '~module/common'
import { useAnimationBlock } from '../animation'
interface IProps { interface IProps {
text: string text: string
onDelete: () => void onDelete: () => void
delay?: number
} }
export const CustomBlock: FC<IProps> = ({ text, onDelete, delay }) => { export const CustomBlock: FC<IProps> = ({ text, onDelete }) => {
const deleteAnim = useRef(new Animated.Value(0)).current const { onPressDelete, animStyle } = useAnimationBlock(onDelete)
const renderAnim = useRef(new Animated.Value(0)).current
const onPressDelete = () => {
Animated.spring(deleteAnim, {
toValue: 1,
useNativeDriver: true,
}).start()
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
setTimeout(onDelete, 200)
}
useEffect(() => {
Animated.spring(renderAnim, {
toValue: 1,
useNativeDriver: true,
delay,
}).start()
}, [])
return ( return (
<Animated.View <Animated.View style={[styles.block, animStyle]}>
style={[
styles.block,
{
transform: [
{
translateX: deleteAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, 400],
}),
},
{
translateY: renderAnim.interpolate({
inputRange: [0, 1],
outputRange: [-100, 0],
}),
},
],
opacity:
renderAnim ||
deleteAnim.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}),
},
]}>
<Txt style={styles.blockTxt}>{text}</Txt> <Txt style={styles.blockTxt}>{text}</Txt>
<TouchableOpacity <TouchableOpacity
style={styles.iconContainer} style={styles.iconContainer}
@ -73,6 +28,7 @@ const styles = StyleSheet.create({
block: { block: {
paddingLeft: 16, paddingLeft: 16,
borderRadius: 20, borderRadius: 20,
paddingVertical: 10,
backgroundColor: colors.darkPurple, backgroundColor: colors.darkPurple,
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
@ -83,8 +39,9 @@ const styles = StyleSheet.create({
fontSize: 16, fontSize: 16,
lineHeight: 24, lineHeight: 24,
color: colors.purple, color: colors.purple,
maxWidth: '80%',
}, },
iconContainer: { iconContainer: {
padding: 16, paddingHorizontal: 16,
}, },
}) })

1
src/module/custom-package/index.ts

@ -1,2 +1,3 @@
export * from './screens' export * from './screens'
export * from './atoms' export * from './atoms'
export * from './animation';

92
src/module/custom-package/screens/custom-package-editor.screen.tsx

@ -10,41 +10,41 @@ import {
StorageKey, StorageKey,
appEvents, appEvents,
colors, colors,
TypeCustom, CustomType,
useAppDispatch,
useNav, useNav,
RouteKey, UserRouteKey,
storageService,
} from '~module/common' } from '~module/common'
import { CustomBlock, EmptyItemsAtom } from '../atoms' import { CustomBlock, EmptyItemsAtom } from '../atoms'
import _ from 'lodash' import _ from 'lodash'
import { useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { import {
addCustomItem,
deleteCustomItem,
selectCustomPackage, selectCustomPackage,
selectCustomPackageFromStore, selectCustomPackageFromStore,
setDares,
setQuestions,
updateCustomPackage, updateCustomPackage,
updateCustomPackageFromStore, updateCustomPackageFromStore,
} from '~store/slices' } from '~store/slices'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
export const CustomPackageEditorScreen: FC = () => { export const CustomPackageEditorScreen: FC = () => {
const dispatch = useAppDispatch() const dispatch = useDispatch()
const { t } = useTranslation() const { t } = useTranslation()
const nav = useNav() const nav = useNav()
const customPackage = useSelector(selectCustomPackage) const customPackage = useSelector(selectCustomPackage)
const customPackageFromStore = useSelector(selectCustomPackageFromStore) const customPackageFromStore = useSelector(selectCustomPackageFromStore)
const isHaveNewChanges = useMemo( const isHaveNewChanges = useMemo(
() => _.isEqual(customPackageFromStore, customPackage), () => _.isEqual(customPackageFromStore, customPackage),
[customPackageFromStore, customPackage], [customPackageFromStore, customPackage],
) )
const [value, setValue] = useState('') const [value, setValue] = useState('')
const [activeMod, setActiveMod] = useState(TypeCustom.Questions) const [activeMod, setActiveMod] = useState(CustomType.Questions)
const onView = (mod: TypeCustom) => { const onViewListByType = (mod: CustomType) => {
setActiveMod(mod) setActiveMod(mod)
} }
@ -52,40 +52,22 @@ export const CustomPackageEditorScreen: FC = () => {
setValue('') setValue('')
} }
const OnAddQuestion = () => { const onAddCustomGameItem = (customType: CustomType) => {
if (!value) return if (!value) return
dispatch(setQuestions([...customPackage.questions, value])) dispatch(addCustomItem({ customType, value }))
setActiveMod(TypeCustom.Questions)
clearValue()
}
const OnAddDare = () => {
if (!value) return
dispatch(setDares([...customPackage.dares, value])) setActiveMod(customType)
setActiveMod(TypeCustom.Dares)
clearValue() clearValue()
} }
const onDeleteItem = (indexItem: number) => { const onDeleteItem = (indexItem: number) => {
const newCustomItems = customPackage[activeMod].filter( dispatch(deleteCustomItem({ customType: activeMod, id: indexItem }))
(it, index) => index !== indexItem,
)
activeMod === TypeCustom.Questions
? dispatch(setQuestions(newCustomItems))
: dispatch(setDares(newCustomItems))
} }
const saveCustomPackage = async () => { const saveCustomPackage = async () => {
try { try {
const newCustomPackage = JSON.stringify(customPackage) await storageService.set(StorageKey.CustomPackage, customPackage)
await AsyncStorage.setItem(
StorageKey.CustomPackage,
newCustomPackage,
)
dispatch(updateCustomPackageFromStore(customPackage)) dispatch(updateCustomPackageFromStore(customPackage))
} catch (error) { } catch (error) {
@ -98,7 +80,7 @@ export const CustomPackageEditorScreen: FC = () => {
saveCustomPackage() saveCustomPackage()
nav.navigate(RouteKey.CustomPackage) nav.navigate(UserRouteKey.CustomPackage)
} }
const goBack = () => { const goBack = () => {
@ -159,7 +141,7 @@ export const CustomPackageEditorScreen: FC = () => {
placeholderTextColor: colors.darkPurple, placeholderTextColor: colors.darkPurple,
}} }}
inputStyle={styles.input} inputStyle={styles.input}
renderClearPostfix={renderClear} renderPostfix={renderClear}
/> />
<View style={styles.line} /> <View style={styles.line} />
@ -168,10 +150,13 @@ export const CustomPackageEditorScreen: FC = () => {
<ButtonPrimary <ButtonPrimary
mb={0} mb={0}
style={styles.btn} style={styles.btn}
onPress={OnAddQuestion}> onPress={() => onAddCustomGameItem(CustomType.Questions)}>
{t('customPack.addTruth')} {t('customPack.addTruth')}
</ButtonPrimary> </ButtonPrimary>
<ButtonPrimary mb={0} style={styles.btn} onPress={OnAddDare}> <ButtonPrimary
mb={0}
style={styles.btn}
onPress={() => onAddCustomGameItem(CustomType.Dares)}>
{t('customPack.addDare')} {t('customPack.addDare')}
</ButtonPrimary> </ButtonPrimary>
</View> </View>
@ -179,24 +164,40 @@ export const CustomPackageEditorScreen: FC = () => {
<View style={[styles.row, { marginTop: 15 }]}> <View style={[styles.row, { marginTop: 15 }]}>
<ButtonPrimary <ButtonPrimary
styleTxt={styles.txt} styleTxt={styles.txt}
style={styles.btnTxt} style={[
styles.btnTxt,
{
borderColor:
activeMod === CustomType.Questions
? colors.turquoise
: colors.darkPurple,
},
]}
txtColor={ txtColor={
activeMod === TypeCustom.Questions activeMod === CustomType.Questions
? colors.turquoise ? colors.turquoise
: colors.purple : colors.purple
} }
onPress={() => onView(TypeCustom.Questions)}> onPress={() => onViewListByType(CustomType.Questions)}>
{t('customPack.viewTruths')} {t('customPack.viewTruths')}
</ButtonPrimary> </ButtonPrimary>
<ButtonPrimary <ButtonPrimary
style={styles.btnTxt} style={[
styles.btnTxt,
{
borderColor:
activeMod === CustomType.Dares
? colors.turquoise
: colors.darkPurple,
},
]}
styleTxt={styles.txt} styleTxt={styles.txt}
txtColor={ txtColor={
activeMod === TypeCustom.Dares activeMod === CustomType.Dares
? colors.turquoise ? colors.turquoise
: colors.purple : colors.purple
} }
onPress={() => onView(TypeCustom.Dares)}> onPress={() => onViewListByType(CustomType.Dares)}>
{t('customPack.viewDares')} {t('customPack.viewDares')}
</ButtonPrimary> </ButtonPrimary>
</View> </View>
@ -208,9 +209,8 @@ export const CustomPackageEditorScreen: FC = () => {
<View style={styles.customBody}> <View style={styles.customBody}>
{customPackage[activeMod].map((it, index) => ( {customPackage[activeMod].map((it, index) => (
<CustomBlock <CustomBlock
key={it} key={it + index}
text={it} text={it}
delay={index * 100}
onDelete={() => onDeleteItem(index)} onDelete={() => onDeleteItem(index)}
/> />
))} ))}
@ -246,7 +246,7 @@ const styles = StyleSheet.create({
btnTxt: { btnTxt: {
backgroundColor: null, backgroundColor: null,
flex: 1, flex: 1,
borderWidth: 2, borderWidth: 1,
borderColor: colors.darkPurple, borderColor: colors.darkPurple,
}, },
txt: { txt: {

41
src/module/custom-package/screens/custom-package-play.screen.tsx

@ -6,14 +6,13 @@ import { useSelector } from 'react-redux'
import { import {
ButtonPrimary, ButtonPrimary,
Header, Header,
ProductsEnum, UserRouteKey,
RouteKey,
ScreenLayout, ScreenLayout,
appEvents, appEvents,
colors, colors,
useNav, useNav,
PackageType,
} from '~module/common' } from '~module/common'
import { purchasesService } from '~module/settings'
import { selectCustomPackage } from '~store/slices' import { selectCustomPackage } from '~store/slices'
export const CustomPackagePreviewScreen: FC = () => { export const CustomPackagePreviewScreen: FC = () => {
@ -22,33 +21,20 @@ export const CustomPackagePreviewScreen: FC = () => {
const customPackage = useSelector(selectCustomPackage) const customPackage = useSelector(selectCustomPackage)
const goToSettings = () => {
nav.navigate(RouteKey.Settings)
}
const goToCustomEditor = () => { const goToCustomEditor = () => {
nav.navigate(RouteKey.CustomEditor) nav.navigate(UserRouteKey.CustomEditor)
} }
const goToGame = () => { const goToGame = () => {
const isPurchased = checkIsPurchasedCustomPack()
if (!isPurchased) return nav.navigate(RouteKey.Purchases)
const isFullCustomPack = checkIsFullCustomPack() const isFullCustomPack = checkIsFullCustomPack()
if (!isFullCustomPack) return if (!isFullCustomPack) return
nav.navigate(RouteKey.Game, { nav.navigate(UserRouteKey.Game, {
packageName: 'My package', packageType: PackageType.Custom,
isCustom: true,
}) })
} }
const checkIsPurchasedCustomPack = () => {
return purchasesService.purchasedProducts.includes(ProductsEnum.All)
}
const checkIsFullCustomPack = () => { const checkIsFullCustomPack = () => {
const isEmptyTruths = _.isEmpty(customPackage.questions) const isEmptyTruths = _.isEmpty(customPackage.questions)
const isEmptyDares = _.isEmpty(customPackage.dares) const isEmptyDares = _.isEmpty(customPackage.dares)
@ -76,23 +62,14 @@ export const CustomPackagePreviewScreen: FC = () => {
return ( return (
<ScreenLayout <ScreenLayout
headerComponent={ headerComponent={<Header title={t('customPack.label')} />}>
<Header
title={t('customPack.label')}
rightIcon="setting"
onPressRight={goToSettings}
/>
}>
<View style={styles.container}> <View style={styles.container}>
<ButtonPrimary <ButtonPrimary
style={styles.editorBtn} style={styles.editorBtn}
onPress={goToCustomEditor}> onPress={goToCustomEditor}>
{t('customPack.editorBtn')} {t('customPack.editorBtn')}
</ButtonPrimary> </ButtonPrimary>
<ButtonPrimary <ButtonPrimary iconName="play" onPress={goToGame}>
style={styles.playBtn}
iconName="play"
onPress={goToGame}>
{t('customPack.play')} {t('customPack.play')}
</ButtonPrimary> </ButtonPrimary>
</View> </View>
@ -109,10 +86,6 @@ const styles = StyleSheet.create({
paddingBottom: 50, paddingBottom: 50,
}, },
playBtn: {
flexDirection: 'row',
columnGap: 8,
},
editorBtn: { editorBtn: {
backgroundColor: colors.darkPurple, backgroundColor: colors.darkPurple,
}, },

35
src/module/game/animations/use-animation-button.ts

@ -3,37 +3,44 @@ import { Animated, Easing } from 'react-native'
import { colors } from '~module/common' import { colors } from '~module/common'
export const useAnimationButton = () => { export const useAnimationButton = () => {
const buttonConfigs = [ const animationsConfig = [
{ delay: 400, ref: useRef(new Animated.Value(0)) }, { delay: 400, value: useRef(new Animated.Value(0)).current },
{ delay: 1200, ref: useRef(new Animated.Value(0)) }, { delay: 1200, value: useRef(new Animated.Value(0)).current },
{ delay: 800, ref: useRef(new Animated.Value(0)) }, { delay: 800, value: useRef(new Animated.Value(0)).current },
] ]
const startAnimationsBorder = buttonConfigs.map( const startAnimationsBorder = animationsConfig.map(
({ delay, ref }) => ({ delay, value }) =>
() => () =>
Animated.timing(ref.current, { Animated.timing(value, {
toValue: 1, toValue: 1,
duration: 600,
delay, delay,
easing: Easing.linear, easing: Easing.linear,
useNativeDriver: true, useNativeDriver: true,
}).start(() => ref.current.setValue(0)), }).start(() => value.setValue(0)),
) )
const interpolatedColors = buttonConfigs.map(({ ref }) => const interpolatedColors = animationsConfig.map(({ value }) =>
ref.current.interpolate({ value.interpolate({
inputRange: [0, 0.5, 1], inputRange: [0, 0.5, 1],
outputRange: [colors.darkPurple, colors.blue, colors.darkPurple], outputRange: [colors.darkPurple, colors.blue, colors.darkPurple],
}), }),
) )
const animBorderStyles = interpolatedColors.map(color => ({ const interpolatedScale = animationsConfig.map(({ value }) =>
borderColor: color, value.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [1, 1.03, 1],
}),
)
const animStyle = interpolatedColors.map((it, index) => ({
borderColor: interpolatedColors[index],
transform: [{ scale: interpolatedScale[index] }],
})) }))
return { return {
animBorderStyles, animStyle,
startAnimationsBorder, startAnimationsBorder,
} }
} }

63
src/module/game/animations/use-animation-truth-or-dare.hook.ts

@ -2,73 +2,26 @@ import { useRef } from 'react'
import { Animated } from 'react-native' import { Animated } from 'react-native'
export const useAnimationTruthOrDare = () => { export const useAnimationTruthOrDare = () => {
const animValue = useRef(new Animated.Value(0)).current const animContainer = useRef(new Animated.Value(400)).current
const animText = useRef(new Animated.Value(1)).current
const startAnimation = () => { const startAnimation = () => {
Animated.sequence([ Animated.timing(animContainer, {
Animated.timing(animText, { toValue: 0,
toValue: 0, duration: 400,
duration: 200, useNativeDriver: true,
useNativeDriver: true, }).start()
}),
Animated.timing(animText, {
toValue: 1,
delay: 400,
useNativeDriver: true,
}),
]).start()
Animated.sequence([
Animated.timing(animValue, {
toValue: 1,
useNativeDriver: true,
}),
Animated.timing(animValue, {
toValue: 0,
useNativeDriver: true,
}),
]).start()
} }
const animStyleContainer = { const animStyleContainer = {
transform: [ transform: [
{ {
translateY: animValue.interpolate({ translateX: animContainer,
inputRange: [0, 1],
outputRange: [0, 20],
}),
},
{
rotateX: animValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '180deg'],
}),
},
],
}
const animStyleText = {
transform: [
{
scale: animText.interpolate({
inputRange: [0, 0.5, 0.75, 1],
outputRange: [0, 0.1, 0.5, 1],
}),
},
{
translateY: animValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 250],
}),
}, },
], ],
} }
return { return {
startAnimation, startAnimation,
animStyle: { animStyle: animStyleContainer,
text: animStyleText,
container: animStyleContainer,
},
} }
} }

1
src/module/game/components/index.ts

@ -1 +1,2 @@
export * from './truth-or-dare-view' export * from './truth-or-dare-view'
export * from './player-field.component';

49
src/module/game/components/player-field.component.tsx

@ -0,0 +1,49 @@
import React, { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet, TouchableOpacity } from 'react-native'
import { FormTextControll, Icon, colors } from '~module/common'
interface IProps {
value: string
onChange: (val: string) => void
onDelete: () => void
}
export const PlayerField: FC<IProps> = ({ value, onChange, onDelete }) => {
const { t } = useTranslation()
const renderClear = () => (
<TouchableOpacity style={styles.clearIcon} onPress={onDelete}>
<Icon name={'clear'} size={24} color={colors.textPrimary} />
</TouchableOpacity>
)
return (
<FormTextControll
value={value}
onChange={onChange}
renderPostfix={renderClear}
inputProps={{
placeholder: t('customPack.placeholder'),
placeholderTextColor: colors.darkPurple,
}}
inputStyle={styles.input}
/>
)
}
const styles = StyleSheet.create({
input: {
borderRadius: 60,
backgroundColor: colors.lightPurple,
borderWidth: 0,
fontSize: 18,
color: colors.purple,
},
clearIcon: {
position: 'absolute',
top: 3,
right: 10,
padding: 10,
},
})

22
src/module/game/components/player-name.component.tsx

@ -0,0 +1,22 @@
import React, { FC } from 'react'
import { StyleSheet } from 'react-native'
import { useSelector } from 'react-redux'
import { Font, Txt } from '~module/common'
import { selectCurrentPlayer } from '~store/slices'
interface IProps {}
export const PlayerName: FC<IProps> = () => {
const playerName = useSelector(selectCurrentPlayer)
return <Txt style={styles.playerName}>{playerName}</Txt>
}
const styles = StyleSheet.create({
playerName: {
fontFamily: Font.Roboto700,
textAlign: 'center',
fontSize: 24,
lineHeight: 34,
},
})

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save