Skip to content

Commit

Permalink
feat(mobile): 💄 update learning flow
Browse files Browse the repository at this point in the history
Signed-off-by: Yunus Andréasson <yunus@edenmind.com>
  • Loading branch information
YunusAndreasson committed Oct 7, 2023
1 parent 7e45bab commit c7aa0af
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 31 deletions.
Binary file modified mobile/.yarn/install-state.gz
Binary file not shown.
Empty file.
6 changes: 3 additions & 3 deletions mobile/components/context-highlighted-word.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import React, { useRef, useState, useEffect, useCallback } from 'react'
import React, { useRef, useState, useEffect } from 'react'
import { Animated, StyleSheet } from 'react-native'
import { Text, useTheme } from 'react-native-paper'

Expand All @@ -22,7 +22,7 @@ const HighlightedWord = ({ word: { arabic } }) => {
})

// eslint-disable-next-line react-hooks/exhaustive-deps
const animateBorderOpacity = useCallback(() => {
const animateBorderOpacity = () => {
const toValue = isBorderVisible ? 0.2 : 1
Animated.timing(borderOpacity, {
duration: 750,
Expand All @@ -31,7 +31,7 @@ const HighlightedWord = ({ word: { arabic } }) => {
}).start(() => {
setIsBorderVisible(!isBorderVisible)
})
})
}

useEffect(() => {
animateBorderOpacity()
Expand Down
22 changes: 16 additions & 6 deletions mobile/hooks/use-practice-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { HOST } from '../constants/urls.js'
import { useAudioPlayer } from '../hooks/use-audio-player.js'
import { getThreeRandomWords } from '../services/utility-service.js'

function useTextPracticeLogic(isComponentVisible = false) {
const audioSelector = (state) => state.audio

function useTextPracticeLogic() {
const getText = (state) => state.text
const { text } = useSelector(getText)
const getTextLoading = (state) => state.textLoading
Expand All @@ -24,6 +26,7 @@ function useTextPracticeLogic(isComponentVisible = false) {
const [sentenceIsComplete, setSentenceIsComplete] = useState(false)
const [celebrationSnackBarVisibility, setCelebrationSnackBarVisibility] = useState(false)
const { playSound } = useAudioPlayer()
const { shouldPlayPracticeWord } = useSelector(audioSelector)

const dispatch = useDispatch()

Expand All @@ -47,14 +50,16 @@ function useTextPracticeLogic(isComponentVisible = false) {

// Play the audio for the current word
useEffect(() => {
if (!isComponentVisible) return // Only play the audio if the component is visible

const wordFilename = sentencesInText?.[currentSentence]?.wordFilename[currentWord]
if (!wordFilename) return

const audioURL = HOST.audio + wordFilename
playSound(audioURL)
}, [currentWord, isComponentVisible])
if (shouldPlayPracticeWord) {
console.log('shouldPlayPracticeWord:', shouldPlayPracticeWord)

playSound(audioURL)
}
}, [currentWord, shouldPlayPracticeWord])

// Update the current sentence and word when the text is loaded
useEffect(() => {
Expand Down Expand Up @@ -93,7 +98,7 @@ function useTextPracticeLogic(isComponentVisible = false) {

// eslint-disable-next-line react-hooks/exhaustive-deps
const handleContinue = () => {
setSentenceIsComplete(false)
setSentenceIsComplete(true)

if (currentSentence === sentencesInText?.length) {
setCelebrationSnackBarVisibility(true)
Expand Down Expand Up @@ -134,6 +139,11 @@ function useTextPracticeLogic(isComponentVisible = false) {
}

if (isLastWordInSentence) {
dispatch({
payload: false,
type: 'SET_AUDIO_SHOULD_PLAY_PRACTICE_WORDS'
})

setSentenceIsComplete(true)

if (isLastSentence) {
Expand Down
2 changes: 1 addition & 1 deletion mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "MIT",
"homepage": "https://openarabic.io",
"repository": "https://github.com/edenmind/OpenArabic",
"version": "1445.2.374",
"version": "1445.2.375",
"authors": [
"Yunus Andreasson <yunus@edenmind.com> (https://github.com/YunusAndreasson)"
],
Expand Down
1 change: 1 addition & 0 deletions mobile/redux/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const RESET_WORDS = createAction('RESET_WORDS')
export const SET_ARABIC_FONT_NAME = createAction('SET_ARABIC_FONT_NAME')
export const SET_ARABIC_FONT_SIZE = createAction('SET_ARABIC_FONT_SIZE')
export const SET_AUDIO = createAction('SET_AUDIO')
export const SET_AUDIO_SHOULD_PLAY_PRACTICE_WORDS = createAction('SET_AUDIO_SHOULD_PLAY_PRACTICE_WORDS')
export const SET_ENG = createAction('SET_ENG')
export const SET_CATEGORIES = createAction('SET_CATEGORIES')
export const SET_DARK_MODE = createAction('SET_DARK_MODE')
Expand Down
14 changes: 10 additions & 4 deletions mobile/redux/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { createReducer } from '@reduxjs/toolkit'
import * as actions from './actions.js'

const initialStateAudio = {
shouldPlay: true
shouldPlay: true,
shouldPlayPracticeWord: false
}
const initialStateCategories = { categories: [] }
const initialStateText = { text: {} }
Expand All @@ -25,9 +26,14 @@ const initialStateUI = {
}

const audioReducer = createReducer(initialStateAudio, (builder) => {
builder.addCase(actions.SET_AUDIO, (state, action) => {
state.shouldPlay = action.payload
})
builder
.addCase(actions.SET_AUDIO, (state, action) => {
state.shouldPlay = action.payload
})
.addCase(actions.SET_AUDIO_SHOULD_PLAY_PRACTICE_WORDS, (state, action) => {
console.log('setting should play practice words to', action.payload)
state.shouldPlayPracticeWord = action.payload
})
})

const UIStateReducer = createReducer(initialStateUI, (builder) => {
Expand Down
4 changes: 4 additions & 0 deletions mobile/screens/text-bilingual.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export default function TextBilingual() {
payload: false,
type: 'SET_AUDIO'
})
dispatch({
payload: false,
type: 'SET_AUDIO_SHOULD_PLAY_PRACTICE_WORDS'
})
}}
/>
</>
Expand Down
1 change: 1 addition & 0 deletions mobile/screens/text-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export default function TextList({ route, navigation }) {
visible={visiblePractice}
content={<Words />}
hideModal={() => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)
setVisiblePractice(false)
}}
/>
Expand Down
28 changes: 12 additions & 16 deletions mobile/screens/text-practice.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
import React, { useState, useEffect } from 'react'
import { View, ScrollView } from 'react-native'
import { useTheme, Divider, ProgressBar } from 'react-native-paper'
import { useDispatch } from 'react-redux'

import { ActionButton } from '../components/action-button.js'
import { AnimatedButton } from '../components/animated-button.js'
Expand All @@ -17,7 +18,7 @@ const TextPractice = () => {
const [showWordsPractice, setShowWordsPractice] = useState(false)
const [isPlaying, setIsPlaying] = useState(false)
const [showRepeat, setShowRepeat] = useState(false)
const [isComponentVisible, setIsComponentVisible] = useState(false)
const dispatch = useDispatch()

const {
isLastSentence,
Expand All @@ -33,22 +34,14 @@ const TextPractice = () => {
handleReset,
handleContinue,
handlePress
} = useTextPracticeLogic(isComponentVisible)
} = useTextPracticeLogic()

useEffect(() => {
if (sentenceIsComplete) {
setShowWordsPractice(false)
}
}, [sentenceIsComplete])

useEffect(() => {
if (showWordsPractice) {
setIsComponentVisible(true)
} else {
setIsComponentVisible(false)
}
}, [showWordsPractice])

const handleStartPractice = () => {
setShowWordsPractice(true)
}
Expand Down Expand Up @@ -84,7 +77,7 @@ const TextPractice = () => {

return textLoading ? (
<>
<ScrollView>
<ScrollView style={{ width: '100%' }}>
<ProgressBar
color={theme.colors.tertiary}
progress={currentSentence / (sentencesInText.length - 1)}
Expand All @@ -100,11 +93,11 @@ const TextPractice = () => {
<PrepareForPractice
{...{
currentSentence,
dispatch,
handleContinue: handleStartPractice,
handleReset,
isLastSentence,
isPlaying,
setIsComponentVisible,
setIsPlaying,
setSentenceIsComplete,
setShowRepeat,
Expand All @@ -126,11 +119,11 @@ const PrepareForPractice = ({
isPlaying,
handleReset,
handleContinue,
setIsComponentVisible,
setIsPlaying,
setSentenceIsComplete,
showRepeat,
setShowRepeat
setShowRepeat,
dispatch
}) => (
<>
<View style={{ position: 'absolute', top: 150, width: '100%' }}>
Expand All @@ -153,10 +146,13 @@ const PrepareForPractice = ({
showRepeat && (
<ActionButton
onPress={() => {
setIsComponentVisible(true)
setSentenceIsComplete(false)
setShowRepeat(false)
handleContinue()
dispatch({
payload: true,
type: 'SET_AUDIO_SHOULD_PLAY_PRACTICE_WORDS'
})
}}
text="CONTINUE"
/>
Expand All @@ -168,11 +164,11 @@ const PrepareForPractice = ({

PrepareForPractice.propTypes = {
currentSentence: PropTypes.number.isRequired,
dispatch: PropTypes.func.isRequired,
handleContinue: PropTypes.func.isRequired,
handleReset: PropTypes.func.isRequired,
isLastSentence: PropTypes.bool.isRequired,
isPlaying: PropTypes.bool.isRequired,
setIsComponentVisible: PropTypes.func.isRequired,
setIsPlaying: PropTypes.func.isRequired,
setSentenceIsComplete: PropTypes.func.isRequired,
setShowRepeat: PropTypes.func.isRequired,
Expand Down
3 changes: 2 additions & 1 deletion mobile/styles/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ export const useSharedStyles = (theme) => {
backgroundColor: theme.colors.elevation.level5,
borderRadius: 10,
height: 15,
marginVertical: 10
marginVertical: 10,
width: '100%'
},
reading: {
color: theme.colors.outline,
Expand Down

0 comments on commit c7aa0af

Please sign in to comment.