@magmamath/students-features 0.4.0 → 0.4.1-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/commonjs/features/endOfAssignment/components/CheatDetected/CheatDetected.js +9 -3
  2. package/dist/commonjs/features/endOfAssignment/components/CheatDetected/CheatDetected.js.map +1 -1
  3. package/dist/commonjs/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.js +7 -1
  4. package/dist/commonjs/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.js.map +1 -1
  5. package/dist/commonjs/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.js +13 -12
  6. package/dist/commonjs/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.js.map +1 -1
  7. package/dist/commonjs/features/endOfAssignment/components/ExamLeave/ExamLeave.js +11 -5
  8. package/dist/commonjs/features/endOfAssignment/components/ExamLeave/ExamLeave.js.map +1 -1
  9. package/dist/commonjs/features/endOfAssignment/components/ExamPaused/ExamPaused.js +9 -3
  10. package/dist/commonjs/features/endOfAssignment/components/ExamPaused/ExamPaused.js.map +1 -1
  11. package/dist/commonjs/features/endOfAssignment/components/ExamSubmit/ExamSubmit.js +11 -5
  12. package/dist/commonjs/features/endOfAssignment/components/ExamSubmit/ExamSubmit.js.map +1 -1
  13. package/dist/commonjs/features/endOfAssignment/components/Modal/Modal.js +1 -1
  14. package/dist/commonjs/features/endOfAssignment/components/Modal/Modal.js.map +1 -1
  15. package/dist/commonjs/features/endOfAssignment/components/NoAnswer/NoAnswer.js +7 -1
  16. package/dist/commonjs/features/endOfAssignment/components/NoAnswer/NoAnswer.js.map +1 -1
  17. package/dist/commonjs/features/endOfAssignment/components/NoAnswer/NoAnswerContent.js +4 -3
  18. package/dist/commonjs/features/endOfAssignment/components/NoAnswer/NoAnswerContent.js.map +1 -1
  19. package/dist/commonjs/features/endOfAssignment/constants.js +5 -1
  20. package/dist/commonjs/features/endOfAssignment/constants.js.map +1 -1
  21. package/dist/commonjs/features/endOfAssignment/hooks/useKeyDownListener.js +27 -0
  22. package/dist/commonjs/features/endOfAssignment/hooks/useKeyDownListener.js.map +1 -0
  23. package/dist/commonjs/features/endOfAssignment/hooks/useKeyboard.js +24 -0
  24. package/dist/commonjs/features/endOfAssignment/hooks/useKeyboard.js.map +1 -0
  25. package/dist/commonjs/features/endOfAssignment/model/model.js +2 -2
  26. package/dist/commonjs/features/endOfAssignment/model/model.js.map +1 -1
  27. package/dist/commonjs/features/endOfAssignment/ui/PracticeButtonGroup.js +4 -5
  28. package/dist/commonjs/features/endOfAssignment/ui/PracticeButtonGroup.js.map +1 -1
  29. package/dist/module/features/endOfAssignment/components/CheatDetected/CheatDetected.js +10 -4
  30. package/dist/module/features/endOfAssignment/components/CheatDetected/CheatDetected.js.map +1 -1
  31. package/dist/module/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.js +8 -2
  32. package/dist/module/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.js.map +1 -1
  33. package/dist/module/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.js +13 -12
  34. package/dist/module/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.js.map +1 -1
  35. package/dist/module/features/endOfAssignment/components/ExamLeave/ExamLeave.js +12 -6
  36. package/dist/module/features/endOfAssignment/components/ExamLeave/ExamLeave.js.map +1 -1
  37. package/dist/module/features/endOfAssignment/components/ExamPaused/ExamPaused.js +10 -4
  38. package/dist/module/features/endOfAssignment/components/ExamPaused/ExamPaused.js.map +1 -1
  39. package/dist/module/features/endOfAssignment/components/ExamSubmit/ExamSubmit.js +12 -6
  40. package/dist/module/features/endOfAssignment/components/ExamSubmit/ExamSubmit.js.map +1 -1
  41. package/dist/module/features/endOfAssignment/components/Modal/Modal.js +1 -1
  42. package/dist/module/features/endOfAssignment/components/Modal/Modal.js.map +1 -1
  43. package/dist/module/features/endOfAssignment/components/NoAnswer/NoAnswer.js +7 -1
  44. package/dist/module/features/endOfAssignment/components/NoAnswer/NoAnswer.js.map +1 -1
  45. package/dist/module/features/endOfAssignment/components/NoAnswer/NoAnswerContent.js +4 -3
  46. package/dist/module/features/endOfAssignment/components/NoAnswer/NoAnswerContent.js.map +1 -1
  47. package/dist/module/features/endOfAssignment/constants.js +4 -0
  48. package/dist/module/features/endOfAssignment/constants.js.map +1 -1
  49. package/dist/module/features/endOfAssignment/hooks/useKeyDownListener.js +22 -0
  50. package/dist/module/features/endOfAssignment/hooks/useKeyDownListener.js.map +1 -0
  51. package/dist/module/features/endOfAssignment/hooks/useKeyboard.js +20 -0
  52. package/dist/module/features/endOfAssignment/hooks/useKeyboard.js.map +1 -0
  53. package/dist/module/features/endOfAssignment/model/model.js +2 -2
  54. package/dist/module/features/endOfAssignment/model/model.js.map +1 -1
  55. package/dist/module/features/endOfAssignment/ui/PracticeButtonGroup.js +5 -6
  56. package/dist/module/features/endOfAssignment/ui/PracticeButtonGroup.js.map +1 -1
  57. package/dist/typescript/commonjs/features/endOfAssignment/components/CheatDetected/CheatDetected.d.ts.map +1 -1
  58. package/dist/typescript/commonjs/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.d.ts.map +1 -1
  59. package/dist/typescript/commonjs/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.d.ts.map +1 -1
  60. package/dist/typescript/commonjs/features/endOfAssignment/components/ExamLeave/ExamLeave.d.ts.map +1 -1
  61. package/dist/typescript/commonjs/features/endOfAssignment/components/ExamPaused/ExamPaused.d.ts.map +1 -1
  62. package/dist/typescript/commonjs/features/endOfAssignment/components/ExamSubmit/ExamSubmit.d.ts.map +1 -1
  63. package/dist/typescript/commonjs/features/endOfAssignment/components/Modal/Modal.d.ts +1 -1
  64. package/dist/typescript/commonjs/features/endOfAssignment/components/Modal/Modal.d.ts.map +1 -1
  65. package/dist/typescript/commonjs/features/endOfAssignment/components/NoAnswer/NoAnswer.d.ts.map +1 -1
  66. package/dist/typescript/commonjs/features/endOfAssignment/constants.d.ts +3 -0
  67. package/dist/typescript/commonjs/features/endOfAssignment/constants.d.ts.map +1 -1
  68. package/dist/typescript/commonjs/features/endOfAssignment/hooks/useKeyDownListener.d.ts +3 -0
  69. package/dist/typescript/commonjs/features/endOfAssignment/hooks/useKeyDownListener.d.ts.map +1 -0
  70. package/dist/typescript/commonjs/features/endOfAssignment/hooks/useKeyboard.d.ts +11 -0
  71. package/dist/typescript/commonjs/features/endOfAssignment/hooks/useKeyboard.d.ts.map +1 -0
  72. package/dist/typescript/commonjs/features/endOfAssignment/model/model.d.ts +1 -1
  73. package/dist/typescript/commonjs/features/endOfAssignment/model/model.d.ts.map +1 -1
  74. package/dist/typescript/commonjs/features/endOfAssignment/ui/PracticeButtonGroup.d.ts +1 -1
  75. package/dist/typescript/commonjs/features/endOfAssignment/ui/PracticeButtonGroup.d.ts.map +1 -1
  76. package/dist/typescript/module/features/endOfAssignment/components/CheatDetected/CheatDetected.d.ts.map +1 -1
  77. package/dist/typescript/module/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.d.ts.map +1 -1
  78. package/dist/typescript/module/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.d.ts.map +1 -1
  79. package/dist/typescript/module/features/endOfAssignment/components/ExamLeave/ExamLeave.d.ts.map +1 -1
  80. package/dist/typescript/module/features/endOfAssignment/components/ExamPaused/ExamPaused.d.ts.map +1 -1
  81. package/dist/typescript/module/features/endOfAssignment/components/ExamSubmit/ExamSubmit.d.ts.map +1 -1
  82. package/dist/typescript/module/features/endOfAssignment/components/Modal/Modal.d.ts +1 -1
  83. package/dist/typescript/module/features/endOfAssignment/components/Modal/Modal.d.ts.map +1 -1
  84. package/dist/typescript/module/features/endOfAssignment/components/NoAnswer/NoAnswer.d.ts.map +1 -1
  85. package/dist/typescript/module/features/endOfAssignment/constants.d.ts +3 -0
  86. package/dist/typescript/module/features/endOfAssignment/constants.d.ts.map +1 -1
  87. package/dist/typescript/module/features/endOfAssignment/hooks/useKeyDownListener.d.ts +3 -0
  88. package/dist/typescript/module/features/endOfAssignment/hooks/useKeyDownListener.d.ts.map +1 -0
  89. package/dist/typescript/module/features/endOfAssignment/hooks/useKeyboard.d.ts +11 -0
  90. package/dist/typescript/module/features/endOfAssignment/hooks/useKeyboard.d.ts.map +1 -0
  91. package/dist/typescript/module/features/endOfAssignment/model/model.d.ts +1 -1
  92. package/dist/typescript/module/features/endOfAssignment/model/model.d.ts.map +1 -1
  93. package/dist/typescript/module/features/endOfAssignment/ui/PracticeButtonGroup.d.ts +1 -1
  94. package/dist/typescript/module/features/endOfAssignment/ui/PracticeButtonGroup.d.ts.map +1 -1
  95. package/package.json +1 -1
  96. package/src/features/endOfAssignment/components/CheatDetected/CheatDetected.tsx +22 -6
  97. package/src/features/endOfAssignment/components/CorrectAnswer/AnimatedCard.tsx +6 -2
  98. package/src/features/endOfAssignment/components/CorrectAnswer/CorrectAnswer.tsx +20 -8
  99. package/src/features/endOfAssignment/components/ExamLeave/ExamLeave.tsx +26 -6
  100. package/src/features/endOfAssignment/components/ExamPaused/ExamPaused.tsx +21 -6
  101. package/src/features/endOfAssignment/components/ExamSubmit/ExamSubmit.tsx +15 -8
  102. package/src/features/endOfAssignment/components/Modal/Modal.tsx +18 -2
  103. package/src/features/endOfAssignment/components/NoAnswer/NoAnswer.tsx +8 -1
  104. package/src/features/endOfAssignment/components/NoAnswer/NoAnswerContent.tsx +2 -1
  105. package/src/features/endOfAssignment/constants.ts +4 -0
  106. package/src/features/endOfAssignment/hooks/useKeyDownListener.ts +26 -0
  107. package/src/features/endOfAssignment/hooks/useKeyboard.ts +19 -0
  108. package/src/features/endOfAssignment/model/model.ts +3 -3
  109. package/src/features/endOfAssignment/ui/PracticeButtonGroup.tsx +6 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyboard.d.ts","sourceRoot":"","sources":["../../../../../../src/features/endOfAssignment/hooks/useKeyboard.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,0GAGtB,CAAC"}
@@ -5,7 +5,7 @@ export declare class EOAModel {
5
5
  readonly practicePressed: import("effector").EventCallable<void>;
6
6
  readonly leavePressed: import("effector").EventCallable<void>;
7
7
  readonly goToFirstProblemPressed: import("effector").EventCallable<void>;
8
- readonly updateRecommendations: import("effector").EventCallable<boolean>;
8
+ readonly recommendationsUpdated: import("effector").EventCallable<boolean>;
9
9
  readonly popUpTriggered: import("effector").EventCallable<EOAEventType>;
10
10
  readonly $popUpData: import("effector").StoreWritable<EOAModalData | null>;
11
11
  readonly $modalVariant: import("effector").StoreWritable<EOAModalVariant | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../../../src/features/endOfAssignment/model/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEtE,qBAAa,QAAQ;IACnB,SAAgB,SAAS,iDAA8B;IACvD,SAAgB,SAAS,yCAAgB;IAEzC,SAAgB,eAAe,yCAAgB;IAC/C,SAAgB,YAAY,yCAAgB;IAC5C,SAAgB,uBAAuB,yCAAgB;IACvD,SAAgB,qBAAqB,4CAAyB;IAC9D,SAAgB,cAAc,iDAA8B;IAE5D,SAAgB,UAAU,wDAGF;IAEtB,SAAgB,aAAa,2DA8BN;IAGzB,SAAgB,iBAAiB,aAGhC;CAEF"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../../../src/features/endOfAssignment/model/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEtE,qBAAa,QAAQ;IACnB,SAAgB,SAAS,iDAA8B;IACvD,SAAgB,SAAS,yCAAgB;IAEzC,SAAgB,eAAe,yCAAgB;IAC/C,SAAgB,YAAY,yCAAgB;IAC5C,SAAgB,uBAAuB,yCAAgB;IACvD,SAAgB,sBAAsB,4CAAyB;IAC/D,SAAgB,cAAc,iDAA8B;IAE5D,SAAgB,UAAU,wDAGF;IAEtB,SAAgB,aAAa,2DA8BN;IAGzB,SAAgB,iBAAiB,aAGhC;CAEF"}
@@ -7,7 +7,7 @@ type PracticeButtonGroupProps = {
7
7
  isPracticeButtonVisible: boolean;
8
8
  onLeftButtonPress: () => void;
9
9
  onRightButtonPress: () => void;
10
- isExam?: boolean;
10
+ isExam: boolean;
11
11
  };
12
12
  export declare const PracticeButtonGroup: ({ textContent, isPracticeButtonVisible, onLeftButtonPress, onRightButtonPress, isExam, }: PracticeButtonGroupProps) => React.JSX.Element;
13
13
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"PracticeButtonGroup.d.ts","sourceRoot":"","sources":["../../../../../../src/features/endOfAssignment/ui/PracticeButtonGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAA;AAexC,KAAK,wBAAwB,GAAG;IAC9B,WAAW,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,uBAAuB,EAAE,OAAO,CAAA;IAChC,iBAAiB,EAAE,MAAM,IAAI,CAAA;IAC7B,kBAAkB,EAAE,MAAM,IAAI,CAAA;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,mBAAmB,6FAM7B,wBAAwB,sBAmC1B,CAAA"}
1
+ {"version":3,"file":"PracticeButtonGroup.d.ts","sourceRoot":"","sources":["../../../../../../src/features/endOfAssignment/ui/PracticeButtonGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAA;AAexC,KAAK,wBAAwB,GAAG;IAC9B,WAAW,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,uBAAuB,EAAE,OAAO,CAAA;IAChC,iBAAiB,EAAE,MAAM,IAAI,CAAA;IAC7B,kBAAkB,EAAE,MAAM,IAAI,CAAA;IAC9B,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,mBAAmB,6FAM7B,wBAAwB,sBAiC1B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magmamath/students-features",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-rc.0",
4
4
  "description": "Magmamath features library",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/commonjs/index.js",
@@ -1,23 +1,39 @@
1
1
  import React from 'react'
2
2
  import { View, StyleSheet } from 'react-native'
3
- import { Button, SPACING, COLORS, Typography } from '@magmamath/react-native-ui'
3
+ import {
4
+ Button,
5
+ SPACING,
6
+ COLORS,
7
+ Typography,
8
+ ButtonVariant,
9
+ ButtonColor,
10
+ ButtonSize,
11
+ } from '@magmamath/react-native-ui'
12
+
4
13
  import { EOAModalContentProps } from '../../types'
14
+ import { useKeyBoard } from '../../hooks/useKeyboard'
5
15
 
6
16
  export const CheatDetected = ({ textContent, model }: EOAModalContentProps) => {
17
+ useKeyBoard((event) => {
18
+ if (event.key === 'Enter') {
19
+ model.hidePopUpAndLeave()
20
+ }
21
+ })
22
+
7
23
  return (
8
24
  <View style={styles.container}>
9
- <Typography variant='h2' style={styles.title}>
25
+ <Typography variant="h2" style={styles.title}>
10
26
  {textContent.title}
11
27
  </Typography>
12
28
 
13
- <Typography variant='h1' style={styles.description}>
29
+ <Typography variant="h1" style={styles.description}>
14
30
  {textContent.description}
15
31
  </Typography>
16
32
 
17
33
  <Button
18
- variant='primary'
19
- colorScheme='red'
20
- size='large'
34
+ variant={ButtonVariant.PRIMARY}
35
+ colorScheme={ButtonColor.RED}
36
+ size={ButtonSize.LARGE}
21
37
  style={{ text: styles.buttonText }}
22
38
  onPress={model.hidePopUpAndLeave}
23
39
  >
@@ -1,5 +1,5 @@
1
1
  import React, { memo, useEffect, useRef } from 'react'
2
- import { View, StyleSheet } from 'react-native'
2
+ import { View, StyleSheet, Text } from 'react-native'
3
3
 
4
4
  import Animated, {
5
5
  useSharedValue,
@@ -208,7 +208,8 @@ export const AnimatedCard = memo(
208
208
  </Typography>
209
209
  {variant === AnimatedCardVariant.CORRECT_ANSWER && (
210
210
  <Typography variant="h5" style={styles.smallText}>
211
- /{problemsAmount}
211
+ <Text style={styles.slash}>{'/'}</Text>
212
+ {problemsAmount}
212
213
  </Typography>
213
214
  )}
214
215
  </View>
@@ -264,6 +265,9 @@ const styles = StyleSheet.create({
264
265
  fontWeight: '700',
265
266
  lineHeight: IS_MOBILE ? 54 : 46,
266
267
  },
268
+ slash: {
269
+ paddingRight: 1,
270
+ },
267
271
  smallText: {
268
272
  fontSize: 16,
269
273
  fontWeight: '700',
@@ -9,14 +9,20 @@ import { AnimatedCard } from './AnimatedCard'
9
9
  import { PracticeButtonGroup } from '../../ui/PracticeButtonGroup'
10
10
  import { GOOD_DRAWING_CARD_APPEARENCE_DELAY } from '../../constants'
11
11
  import { AnimatedCardVariant, EOAModalContentProps, EOAModalVariant } from '../../types'
12
+ import { useKeyBoard } from '../../hooks/useKeyboard'
12
13
 
13
14
  export const CorrectAnswer = ({ textContent, model, onPracticePress }: EOAModalContentProps) => {
14
15
  const popUpData = useUnit(model.$popUpData)
15
16
  const modalVariant = useUnit(model.$modalVariant)
16
17
  const [cardsAnimationCompleted, setCardsAnimationCompleted] = useState(false)
17
18
 
18
- const { user, stats, hasRecommendations, isExam, newerAssignmentAvailable } = popUpData ?? {}
19
- const { solvedAmount, problemsAmount, goodDrawingAmount } = stats ?? {}
19
+ const {
20
+ user,
21
+ stats,
22
+ hasRecommendations,
23
+ isExam = false,
24
+ newerAssignmentAvailable,
25
+ } = popUpData ?? {}
20
26
 
21
27
  const isPracticeButtonVisible = !!(
22
28
  user?.practiceMode &&
@@ -24,13 +30,13 @@ export const CorrectAnswer = ({ textContent, model, onPracticePress }: EOAModalC
24
30
  (isExam || hasRecommendations)
25
31
  )
26
32
 
27
- const handlePracticePress = () => {
33
+ const handlePracticeButtonPress = () => {
28
34
  onPracticePress?.()
29
35
  model.hidePopUp()
30
36
  }
31
37
 
32
38
  const onCorrectAnswerAnimationEnd = useCallback(() => {
33
- if (goodDrawingAmount === 0) {
39
+ if (stats?.goodDrawingAmount === 0) {
34
40
  setCardsAnimationCompleted(true)
35
41
  }
36
42
  }, [])
@@ -39,6 +45,12 @@ export const CorrectAnswer = ({ textContent, model, onPracticePress }: EOAModalC
39
45
  setCardsAnimationCompleted(true)
40
46
  }, [])
41
47
 
48
+ useKeyBoard((event) => {
49
+ if (event.key === 'Enter') {
50
+ isPracticeButtonVisible ? handlePracticeButtonPress() : model.hidePopUpAndLeave()
51
+ }
52
+ })
53
+
42
54
  return (
43
55
  <View
44
56
  style={[
@@ -59,8 +71,8 @@ export const CorrectAnswer = ({ textContent, model, onPracticePress }: EOAModalC
59
71
  <AnimatedCard
60
72
  variant={AnimatedCardVariant.CORRECT_ANSWER}
61
73
  textContent={textContent}
62
- solvedAmount={solvedAmount}
63
- problemsAmount={problemsAmount}
74
+ solvedAmount={stats?.solvedAmount}
75
+ problemsAmount={stats?.problemsAmount}
64
76
  shouldTriggerSparkles={cardsAnimationCompleted}
65
77
  onAnimationEnd={onCorrectAnswerAnimationEnd}
66
78
  />
@@ -69,7 +81,7 @@ export const CorrectAnswer = ({ textContent, model, onPracticePress }: EOAModalC
69
81
  <AnimatedCard
70
82
  variant={AnimatedCardVariant.GOOD_DRAWING}
71
83
  textContent={textContent}
72
- gbdAmount={goodDrawingAmount}
84
+ gbdAmount={stats?.goodDrawingAmount}
73
85
  shouldTriggerSparkles={cardsAnimationCompleted}
74
86
  onAnimationEnd={onGBDAnimationEnd}
75
87
  delay={GOOD_DRAWING_CARD_APPEARENCE_DELAY}
@@ -82,7 +94,7 @@ export const CorrectAnswer = ({ textContent, model, onPracticePress }: EOAModalC
82
94
  isPracticeButtonVisible={isPracticeButtonVisible}
83
95
  isExam={isExam}
84
96
  onLeftButtonPress={model.hidePopUpAndLeave}
85
- onRightButtonPress={handlePracticePress}
97
+ onRightButtonPress={handlePracticeButtonPress}
86
98
  />
87
99
  </View>
88
100
  )
@@ -1,27 +1,47 @@
1
1
  import React from 'react'
2
2
  import { View, StyleSheet } from 'react-native'
3
- import { Button, COLORS, SPACING, Typography } from '@magmamath/react-native-ui'
3
+ import {
4
+ Button,
5
+ ButtonColor,
6
+ ButtonSize,
7
+ ButtonVariant,
8
+ COLORS,
9
+ SPACING,
10
+ Typography,
11
+ } from '@magmamath/react-native-ui'
4
12
 
5
13
  import { EOAModalContentProps } from '../../types'
14
+ import { useKeyBoard } from '../../hooks/useKeyboard'
6
15
 
7
16
  export const ExamLeave = ({ textContent, model }: EOAModalContentProps) => {
8
17
  const handleDismiss = () => model.hidePopUp()
9
18
 
19
+ useKeyBoard((event) => {
20
+ if (event.key === 'Enter') {
21
+ model.hidePopUpAndLeave()
22
+ }
23
+ })
24
+
10
25
  return (
11
26
  <View style={styles.container}>
12
- <Typography variant='h1' style={styles.description}>
27
+ <Typography variant="h1" style={styles.description}>
13
28
  {textContent.description}
14
29
  </Typography>
15
30
 
16
31
  <View style={styles.buttonsContainer}>
17
- <Button variant='tertiary' size='large' style={{ text: styles.buttonText }} onPress={handleDismiss}>
32
+ <Button
33
+ variant={ButtonVariant.TERTIARY}
34
+ size={ButtonSize.LARGE}
35
+ style={{ text: styles.buttonText }}
36
+ onPress={handleDismiss}
37
+ >
18
38
  {textContent.leftButtonText}
19
39
  </Button>
20
40
 
21
41
  <Button
22
- variant='primary'
23
- colorScheme='red'
24
- size='large'
42
+ variant={ButtonVariant.PRIMARY}
43
+ colorScheme={ButtonColor.RED}
44
+ size={ButtonSize.LARGE}
25
45
  style={{ text: styles.buttonText }}
26
46
  onPress={model.hidePopUpAndLeave}
27
47
  >
@@ -1,24 +1,39 @@
1
1
  import React from 'react'
2
2
  import { View, StyleSheet } from 'react-native'
3
- import { Button, COLORS, SPACING, Typography } from '@magmamath/react-native-ui'
3
+ import {
4
+ Button,
5
+ ButtonColor,
6
+ ButtonSize,
7
+ ButtonVariant,
8
+ COLORS,
9
+ SPACING,
10
+ Typography,
11
+ } from '@magmamath/react-native-ui'
4
12
 
5
13
  import { EOAModalContentProps } from '../../types'
14
+ import { useKeyBoard } from '../../hooks/useKeyboard'
6
15
 
7
16
  export const ExamPaused = ({ textContent, model }: EOAModalContentProps) => {
17
+ useKeyBoard((event) => {
18
+ if (event.key === 'Enter') {
19
+ model.hidePopUpAndLeave()
20
+ }
21
+ })
22
+
8
23
  return (
9
24
  <View style={styles.container}>
10
- <Typography variant='h2' style={styles.title}>
25
+ <Typography variant="h2" style={styles.title}>
11
26
  {textContent.title}
12
27
  </Typography>
13
28
 
14
- <Typography variant='h1' style={styles.description}>
29
+ <Typography variant="h1" style={styles.description}>
15
30
  {textContent.description}
16
31
  </Typography>
17
32
 
18
33
  <Button
19
- variant='primary'
20
- colorScheme='purple'
21
- size='large'
34
+ variant={ButtonVariant.PRIMARY}
35
+ colorScheme={ButtonColor.PURPLE}
36
+ size={ButtonSize.LARGE}
22
37
  style={{ text: styles.buttonText }}
23
38
  onPress={model.hidePopUpAndLeave}
24
39
  >
@@ -1,8 +1,11 @@
1
1
  import React from 'react'
2
2
  import { View, StyleSheet, Platform, Image } from 'react-native'
3
+
3
4
  import { useUnit } from 'effector-react'
4
5
  import {
5
6
  Button,
7
+ ButtonColor,
8
+ ButtonSize,
6
9
  ButtonVariant,
7
10
  COLORS,
8
11
  IS_MOBILE,
@@ -13,6 +16,7 @@ import {
13
16
  import { ExamSubmitContent } from './ExamSubmitContent'
14
17
  import { EOAModalContentProps } from '../../types'
15
18
  import { PracticeButton } from '../../ui/PracticeButton'
19
+ import { useKeyBoard } from '../../hooks/useKeyboard'
16
20
 
17
21
  export const ExamSubmit = ({ textContent, model, onPracticePress }: EOAModalContentProps) => {
18
22
  const popUpData = useUnit(model.$popUpData)
@@ -20,16 +24,19 @@ export const ExamSubmit = ({ textContent, model, onPracticePress }: EOAModalCont
20
24
  const problemsAmount = popUpData?.stats?.problemsAmount ?? 0
21
25
  const practiceModeEnabled = popUpData?.user.practiceMode
22
26
 
23
- const leaveAssignmentButtonVariant =
24
- !practiceModeEnabled || popUpData?.newerAssignmentAvailable
25
- ? ButtonVariant.PRIMARY
26
- : ButtonVariant.TERTIARY
27
+ const isPracticeButtonVisible = !!practiceModeEnabled && !popUpData?.newerAssignmentAvailable
27
28
 
28
29
  const handlePracticePress = () => {
29
30
  onPracticePress?.()
30
31
  model.hidePopUp()
31
32
  }
32
33
 
34
+ useKeyBoard((event) => {
35
+ if (event.key === 'Enter') {
36
+ isPracticeButtonVisible ? handlePracticePress() : model.hidePopUpAndLeave()
37
+ }
38
+ })
39
+
33
40
  return (
34
41
  <View style={styles.container}>
35
42
  <View style={styles.contentBackground}>
@@ -48,15 +55,15 @@ export const ExamSubmit = ({ textContent, model, onPracticePress }: EOAModalCont
48
55
 
49
56
  <View style={styles.buttonsContainer}>
50
57
  <Button
51
- variant={leaveAssignmentButtonVariant}
52
- size="large"
53
- colorScheme={popUpData?.isExam ? 'purple' : 'blue'}
58
+ variant={isPracticeButtonVisible ? ButtonVariant.TERTIARY : ButtonVariant.PRIMARY}
59
+ size={ButtonSize.LARGE}
60
+ colorScheme={popUpData?.isExam ? ButtonColor.PURPLE : ButtonColor.BLUE}
54
61
  style={{ text: { textTransform: 'uppercase' } }}
55
62
  onPress={model.hidePopUpAndLeave}
56
63
  >
57
64
  {textContent.leftButtonText ?? ''}
58
65
  </Button>
59
- {!!practiceModeEnabled && !popUpData?.newerAssignmentAvailable && (
66
+ {isPracticeButtonVisible && (
60
67
  <PracticeButton onPress={handlePracticePress} text={textContent.rightButtonText} />
61
68
  )}
62
69
  </View>
@@ -1,5 +1,4 @@
1
1
  import React, { ReactNode, useEffect, useState } from 'react'
2
- import { ButtonVariant, CrossIcon, COLORS, BORDER_RADIUS, SPACING, SHADOWS, Button } from '@magmamath/react-native-ui'
3
2
  import {
4
3
  Animated,
5
4
  GestureResponderEvent,
@@ -11,6 +10,16 @@ import {
11
10
  ViewStyle,
12
11
  } from 'react-native'
13
12
 
13
+ import {
14
+ ButtonVariant,
15
+ CrossIcon,
16
+ COLORS,
17
+ BORDER_RADIUS,
18
+ SPACING,
19
+ SHADOWS,
20
+ Button,
21
+ } from '@magmamath/react-native-ui'
22
+
14
23
  import { ModalModel } from './model'
15
24
  import { ModalBackground } from './ModalBackground'
16
25
 
@@ -40,7 +49,14 @@ export type ModalProps = {
40
49
  }
41
50
  }
42
51
 
43
- export const Modal = ({ isVisible, isDismissable = true, onClose, style, content, withBackground }: ModalProps) => {
52
+ export const Modal = ({
53
+ isVisible,
54
+ isDismissable = true,
55
+ onClose,
56
+ style,
57
+ content,
58
+ withBackground,
59
+ }: ModalProps) => {
44
60
  const [modalModel] = useState(() => new ModalModel())
45
61
 
46
62
  useEffect(() => {
@@ -13,6 +13,7 @@ import {
13
13
  import { EOAModalContentProps } from '../../types'
14
14
  import { NoAnswerContent } from './NoAnswerContent'
15
15
  import { PracticeButton } from '../../ui/PracticeButton'
16
+ import { useKeyBoard } from '../../hooks/useKeyboard'
16
17
 
17
18
  export const NoAnswer = ({ model, textContent, onPracticePress }: EOAModalContentProps) => {
18
19
  const popUpData = useUnit(model.$popUpData)
@@ -30,6 +31,12 @@ export const NoAnswer = ({ model, textContent, onPracticePress }: EOAModalConten
30
31
  model.hidePopUp()
31
32
  }
32
33
 
34
+ useKeyBoard((event) => {
35
+ if (event.key === 'Enter') {
36
+ practiceButtonVisible ? handlePrimaryButtonPress() : model.hidePopUpAndLeave
37
+ }
38
+ })
39
+
33
40
  return (
34
41
  <View style={styles.container}>
35
42
  <View style={styles.container}>
@@ -49,7 +56,7 @@ export const NoAnswer = ({ model, textContent, onPracticePress }: EOAModalConten
49
56
  <Button
50
57
  variant={practiceButtonVisible ? ButtonVariant.TERTIARY : ButtonVariant.PRIMARY}
51
58
  size="large"
52
- colorScheme={popUpData?.isExam ? 'purple' : 'blue'}
59
+ colorScheme={popUpData?.isExam ? ButtonColor.PURPLE : ButtonColor.BLUE}
53
60
  style={{ text: { textTransform: 'uppercase' } }}
54
61
  onPress={model.hidePopUpAndLeave}
55
62
  >
@@ -47,7 +47,7 @@ export const NoAnswerContent = ({ solvedAmount, problemsAmount }: NoAnswerConten
47
47
  {solvedAmount}
48
48
  </Typography>
49
49
  <Typography style={styles.text}>
50
- <Text style={{ paddingRight: 1 }}>{'/'}</Text>
50
+ <Text style={styles.slash}>{'/'}</Text>
51
51
  {problemsAmount}
52
52
  </Typography>
53
53
  </View>
@@ -104,4 +104,5 @@ const styles = StyleSheet.create({
104
104
  fontWeight: '700',
105
105
  color: '#E0E0E0',
106
106
  },
107
+ slash: { paddingRight: 1 },
107
108
  })
@@ -5,6 +5,10 @@ import { AnimatedCardVariant, EOAModalVariant } from './types'
5
5
  export const SPARKS_ANIMATION_DELAY = 2000
6
6
  export const GOOD_DRAWING_CARD_APPEARENCE_DELAY = 1800
7
7
 
8
+ export enum KeyboardKeys {
9
+ ENTER = 'Enter',
10
+ }
11
+
8
12
  export const MODALS_WITH_BACKGROUND = [
9
13
  EOAModalVariant.HAS_CORRECT_ANSWERS,
10
14
  EOAModalVariant.HAS_GOOD_DRAWING,
@@ -0,0 +1,26 @@
1
+ import { useEffect, useRef } from 'react'
2
+ import { KeyboardKeys } from '../constants'
3
+
4
+ export const useKeyDownListener = (
5
+ callback: (event: KeyboardEvent) => void,
6
+ overrideKeys = [KeyboardKeys.ENTER],
7
+ ) => {
8
+ const callbackRef = useRef(callback)
9
+ callbackRef.current = callback
10
+
11
+ useEffect(() => {
12
+ const eventHandler = (event: KeyboardEvent) => {
13
+ if (overrideKeys.includes(event.key as KeyboardKeys)) {
14
+ event.preventDefault()
15
+ event.stopPropagation()
16
+ }
17
+
18
+ callbackRef.current(event)
19
+ }
20
+
21
+ document.addEventListener('keydown', eventHandler, true)
22
+ return () => {
23
+ document.removeEventListener('keydown', eventHandler, true)
24
+ }
25
+ }, [])
26
+ }
@@ -0,0 +1,19 @@
1
+ import { Platform } from 'react-native';
2
+ import { useKeyDownListener } from './useKeyDownListener';
3
+
4
+
5
+ const noop = () => {};
6
+
7
+ /**
8
+ * A cross-platform hook for handling keyboard events.
9
+ *
10
+ * - On native platforms (iOS, Android), it returns a no-op function because
11
+ * keyboard events are generally not applicable.
12
+ *
13
+ * - On web (default), it returns the `useKeyDownListener` hook, which allows you
14
+ * to register a callback that is triggered on keydown events.
15
+ */
16
+ export const useKeyBoard = Platform.select({
17
+ native: noop,
18
+ default: useKeyDownListener,
19
+ });
@@ -1,4 +1,4 @@
1
- import { createStore, createEvent, sample } from 'effector'
1
+ import { createStore, createEvent } from 'effector'
2
2
  import { EOAModalVariant, EOAModalData, EOAEventType } from '../types'
3
3
 
4
4
  export class EOAModel {
@@ -8,12 +8,12 @@ export class EOAModel {
8
8
  public readonly practicePressed = createEvent()
9
9
  public readonly leavePressed = createEvent()
10
10
  public readonly goToFirstProblemPressed = createEvent()
11
- public readonly updateRecommendations = createEvent<boolean>()
11
+ public readonly recommendationsUpdated = createEvent<boolean>()
12
12
  public readonly popUpTriggered = createEvent<EOAEventType>()
13
13
 
14
14
  public readonly $popUpData = createStore<EOAModalData | null>(null)
15
15
  .on(this.showPopUp, (_, payload) => payload)
16
- .on(this.updateRecommendations, (state, hasRecommendations) => (state ? { ...state, hasRecommendations } : state))
16
+ .on(this.recommendationsUpdated, (state, hasRecommendations) => (state ? { ...state, hasRecommendations } : state))
17
17
  .reset(this.hidePopUp)
18
18
 
19
19
  public readonly $modalVariant = createStore<EOAModalVariant | null>(null)
@@ -9,7 +9,7 @@ import Animated, {
9
9
  FadeInUp,
10
10
  withTiming,
11
11
  } from 'react-native-reanimated'
12
- import { ButtonVariant, SPACING, Button } from '@magmamath/react-native-ui'
12
+ import { ButtonVariant, SPACING, Button, ButtonSize, ButtonColor } from '@magmamath/react-native-ui'
13
13
 
14
14
  import { PracticeButton } from './PracticeButton'
15
15
 
@@ -18,7 +18,7 @@ type PracticeButtonGroupProps = {
18
18
  isPracticeButtonVisible: boolean
19
19
  onLeftButtonPress: () => void
20
20
  onRightButtonPress: () => void
21
- isExam?: boolean
21
+ isExam: boolean
22
22
  }
23
23
 
24
24
  export const PracticeButtonGroup = ({
@@ -30,8 +30,6 @@ export const PracticeButtonGroup = ({
30
30
  }: PracticeButtonGroupProps) => {
31
31
  const buttonsContainerOpacity = useSharedValue(0)
32
32
 
33
- console.log('rerender')
34
-
35
33
  useEffect(() => {
36
34
  buttonsContainerOpacity.value = withDelay(1000, withTiming(1, { duration: 500 }))
37
35
  }, [])
@@ -47,17 +45,17 @@ export const PracticeButtonGroup = ({
47
45
  >
48
46
  <Button
49
47
  variant={isPracticeButtonVisible ? ButtonVariant.TERTIARY : ButtonVariant.PRIMARY}
50
- size="large"
51
- colorScheme={isExam ? 'purple' : 'blue'}
48
+ size={ButtonSize.LARGE}
49
+ colorScheme={isExam ? ButtonColor.PURPLE : ButtonColor.BLUE}
52
50
  style={{ text: { textTransform: 'uppercase' } }}
53
51
  onPress={onLeftButtonPress}
54
52
  >
55
- {textContent.leftButtonText ?? ''}
53
+ {textContent.leftButtonText}
56
54
  </Button>
57
55
  </Animated.View>
58
56
  <Animated.View>
59
57
  {isPracticeButtonVisible && (
60
- <PracticeButton onPress={onRightButtonPress} text={textContent.rightButtonText ?? ''} />
58
+ <PracticeButton onPress={onRightButtonPress} text={textContent.rightButtonText} />
61
59
  )}
62
60
  </Animated.View>
63
61
  </Animated.View>