Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YunusAndreasson/issue2209 #2223

Merged
merged 2 commits into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified api/.yarn/install-state.gz
Binary file not shown.
Empty file added api/.yarn/versions/a865d729.yml
Empty file.
2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"license": "MIT",
"homepage": "https://openarabic.io",
"repository": "https://github.com/edenmind/OpenArabic",
"version": "1444.12.229",
"version": "1444.12.231",
"authors": [
"Yunus Andreasson <[email protected]> (https://github.com/YunusAndreasson)"
],
Expand Down
8 changes: 6 additions & 2 deletions api/schemas/texts.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const getTextsOptions = {
handler: listTexts
}

// used for categories
const getTextsWithIdOptions = {
schema: {
response: {
Expand Down Expand Up @@ -80,6 +81,7 @@ const getTextOptions = {
slug: { type: 'string' },
image: { type: 'string' },
introduction: { type: 'string' },
explanation: { type: 'string' },
views: { type: 'string' },
timeAgo: { type: 'string' },
readingTime: { type: 'string' },
Expand Down Expand Up @@ -147,7 +149,8 @@ const updateTextOptions = {
properties: {
quiz: { type: 'boolean' },
arabic: { type: 'string', minLength: 1, maxLength: 50 },
english: { type: 'string', minLength: 1, maxLength: 50 }
english: { type: 'string', minLength: 1, maxLength: 50 },
explanation: { type: 'string' }
}
}
}
Expand Down Expand Up @@ -208,7 +211,8 @@ const postTextOptions = {
properties: {
quiz: { type: 'boolean' },
arabic: { type: 'string', maxLength: 50 },
english: { type: 'string', maxLength: 50 }
english: { type: 'string', maxLength: 50 },
explanation: { type: 'string' }
}
}
}
Expand Down
1 change: 1 addition & 0 deletions api/schemas/words.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ const getWordsOptions = {
grammar: { type: 'string' },
filename: { type: 'string' },
date: { type: 'string' },
explanation: { type: 'string' },
publishDate: { type: 'string' },
arabicSentenceFilename: { type: 'string' }
}
Expand Down
1 change: 1 addition & 0 deletions api/services/texts.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ async function getAllWordsFromTexts(textsCollection) {
arabicSentence: sentence.arabic,
englishSentence: sentence.english,
audioSentence: sentence.filename,
explanation: sentence.explanation,
author: text.author,
source: text.source,
arabicSentenceFilename: sentence.filename
Expand Down
Binary file modified mobile/.yarn/install-state.gz
Binary file not shown.
Empty file.
1 change: 1 addition & 0 deletions mobile/components/modal-scroll-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ModalScrollView = ({
...sharedStyled.arabicHeading,
alignSelf: 'center',
marginHorizontal: 10,
paddingBottom: 15,
textAlign: 'center',
writingDirection: 'rtl'
},
Expand Down
14 changes: 9 additions & 5 deletions mobile/components/play-sound.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import PropTypes from 'prop-types'
import { StyleSheet } from 'react-native'

// This is more of a component than a server and might be better placed in the components folder
export default function PlaySound({ audioFileNames, buttonText }) {
export default function PlaySound({ audioFileNames, buttonText, mode = 'elevated', margin = 10 }) {
const [sound, setSound] = React.useState()

const styles = StyleSheet.create({
button: {
marginBottom: 10,
marginTop: 10
marginBottom: margin,
marginTop: margin
}
})

// function that loops over audioFileName that is an array and calls playSound with the should that should be played
const playAllSounds = async () => {
console.log(audioFileNames)

if (Array.isArray(audioFileNames)) {
for (const audioFileName of audioFileNames) {
await playSound(audioFileName)
Expand Down Expand Up @@ -69,13 +71,15 @@ export default function PlaySound({ audioFileNames, buttonText }) {
}, [sound])

return (
<Button onPress={playAllSounds} mode="elevated" style={styles.button} icon={'play'}>
<Button onPress={playAllSounds} mode={mode} style={styles.button} icon={'play'}>
{buttonText}
</Button>
)
}

PlaySound.propTypes = {
mode: PropTypes.string,
audioFileNames: PropTypes.any.isRequired,
buttonText: PropTypes.string.isRequired
buttonText: PropTypes.string.isRequired,
margin: PropTypes.number
}
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": "1444.12.329",
"version": "1444.12.331",
"authors": [
"Yunus Andreasson <[email protected]> (https://github.com/YunusAndreasson)"
],
Expand Down
2 changes: 1 addition & 1 deletion mobile/screens/text-bilingual-heading.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ TextBilingualHeading.propTypes = {
image: PropTypes.string.isRequired,
author: PropTypes.string.isRequired,
source: PropTypes.string.isRequired,
introduction: PropTypes.string.isOptional
introduction: PropTypes.string
})
}
6 changes: 5 additions & 1 deletion mobile/screens/text-bilingual-sentences-word-pair.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import { StyleSheet, View } from 'react-native'
import { Text, useTheme } from 'react-native-paper'
import { Text, useTheme, Button } from 'react-native-paper'
import PlaySound from '../components/play-sound.js'
import { useSharedStyles } from '../styles/common.js'
import ModalScrollView from '../components/modal-scroll-view.js'
Expand All @@ -25,6 +25,7 @@ function TextBilingualSentencesWords({ word }) {
const sharedStyle = useSharedStyles(theme)
const [visible, setVisible] = React.useState(false)
const hideModal = () => setVisible(false)
const showModal = () => setVisible(true)

const explanation = formatGrammar(word.grammar, sharedStyle)

Expand All @@ -39,6 +40,9 @@ function TextBilingualSentencesWords({ word }) {
</View>
<View style={styles.flexOne}>
<PlaySound audioFileNames={word.filename} buttonText={UI.play} />
<Button mode="elevated" textColor={theme.colors.tertiary} onPress={showModal} icon="eye-outline">
{UI.explain}
</Button>
</View>
</View>
<ModalScrollView
Expand Down
2 changes: 1 addition & 1 deletion mobile/screens/text-bilingual-sentences.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function TextBilingualSentences(props) {
<Button
mode="elevated"
textColor={theme.colors.tertiary}
icon="abjad-arabic"
icon="eye-outline"
onPress={() => {
getListOfWordPairs(<WordPairs words={util.filterArrayFromEmptyElements(sentence.words, filterFunction)} />)
showModal()
Expand Down
5 changes: 5 additions & 0 deletions mobile/screens/text-list-card-quote.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
import React, { useState, useCallback } from 'react'
import { StyleSheet, Animated, Share } from 'react-native'
import { useSharedStyles } from '../styles/common.js'
import PlaySound from '../components/play-sound.js'

export default function TextListCardQuote({ text }) {
const [scaleValue] = useState(new Animated.Value(1))
Expand Down Expand Up @@ -87,6 +88,10 @@ export default function TextListCardQuote({ text }) {
New ☀️
</Chip>
)}
<PlaySound
audioFileNames={`https://openarabic.ams3.digitaloceanspaces.com/audio/${text.sentences[0].filename}`}
buttonText={'Play'}
/>
<Button onPress={onShare}>Share</Button>
</Card.Actions>
</Card>
Expand Down
58 changes: 52 additions & 6 deletions mobile/screens/text-practice.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { View, ScrollView, Alert } from 'react-native'
import { Text, Surface, Divider, useTheme } from 'react-native-paper'
import { Text, Surface, Divider, useTheme, Button } from 'react-native-paper'
import { useSelector } from 'react-redux'
import React, { useState, useEffect, useCallback } from 'react'
import { useSharedStyles } from '../styles/common.js'
Expand All @@ -8,6 +8,9 @@ import WordsContextHighLighted from '../components/context-highlighted.js'
import TextPracticeArabicWords from './text-practice-arabic-words.js'
import { getThreeRandomWords, vibrateBetweenTwoColors } from '../services/utility-service.js'
import Spinner from '../components/spinner.js'
import ModalScrollView from '../components/modal-scroll-view.js'
import { formatGrammar } from '../services/ui-services.js'
import PlaySound from '../components/play-sound.js'

const selector = (state) => state.text
const textLoadSelector = (state) => state.textLoading
Expand All @@ -22,6 +25,9 @@ const TextPractice = () => {
const [currentArabicWordsInSentence, setCurrentArabicWordsInSentence] = useState([])
const [color, setColor] = useState(theme.colors.elevation.level2)
const [currentEnglishWord, setCurrentEnglishWord] = useState(0)
const hideModal = () => setVisible(false)
const [visible, setVisible] = React.useState(false)
const [explanation, setExplanation] = useState('')

// update the state for currentArabicWordsInSentence with the arabic words in the current sentence (sentencesInText[currentSentence].arabicWords) when the component loads
useEffect(() => {
Expand Down Expand Up @@ -64,16 +70,17 @@ const TextPractice = () => {
const wordsInSentence = sentence.words.map((word, wordIndex) => {
return {
arabicWord: { arabic: word.arabic, id: wordIndex },
englishWord: { english: word.english, id: wordIndex }
englishWord: { english: word.english, id: wordIndex },
explanation: word.explanation
}
})

const arabicWords = wordsInSentence.map((word) => word.arabicWord).sort(() => Math.random() - 0.5)
const englishWords = wordsInSentence.map((word) => word.englishWord)
const explanations = wordsInSentence.map((word) => word.explanation)
const filename = sentence.filename

const explanation = sentence.explanation

return { arabicWords, englishWords, explanation }
return { arabicWords, englishWords, explanations, filename }
})
}, [text])

Expand Down Expand Up @@ -147,9 +154,48 @@ const TextPractice = () => {
englishWord={currentEnglishWord}
/>
</View>
<View style={{ position: 'absolute', right: 10, bottom: 20, flexDirection: 'row' }}>
<Button
mode="contained-tonal"
style={{ marginHorizontal: 5 }}
icon="eye-outline"
onPress={() => {
let combinedExplanations = ''

for (const [index, word] of sentencesInText[currentSentence].englishWords.entries()) {
const currentEnglishWord = word.english.charAt(0).toUpperCase() + word.english.slice(1)
const currentArabicWord = sentencesInText[currentSentence].arabicWords[index].arabic
const currentExplanation = sentencesInText[currentSentence].explanations[index]

combinedExplanations += `⟶ ${currentArabicWord}\n↠ ${currentEnglishWord}\n${currentExplanation}\n\n`
}

setExplanation(formatGrammar(combinedExplanations, sharedStyle))
setVisible(true)
}}
>
Explain
</Button>
<PlaySound
audioFileNames={sentencesInText[currentSentence].filename}
buttonText="Play"
margin={0}
mode="contained-tonal"
/>
<Button mode="contained" style={{ marginHorizontal: 5 }}>
Next
</Button>
</View>
</Surface>

<Divider style={{ ...sharedStyle.divider, opacity: 0 }} />
<ModalScrollView
visible={visible}
titleLanguage="english"
content={<View>{explanation}</View>}
title={'Explain'}
hideModal={hideModal}
/>

<TextPracticeArabicWords
testID="textPracticeArabicWords"
currentArabicWordsInSentence={currentArabicWordsInSentence}
Expand Down
63 changes: 27 additions & 36 deletions mobile/screens/words-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ import * as Haptics from 'expo-haptics'
import PropTypes from 'prop-types'
import PlaySound from '../components/play-sound.js'
import { vibrateBetweenTwoColors, generateRandomPositions } from '../services/utility-service.js'
import ModalScrollView from '../components/modal-scroll-view.js'
import { formatGrammar } from '../services/ui-services.js'

const wordsSelector = (state) => state.words

const WordsContent = ({
Expand All @@ -31,8 +28,6 @@ const WordsContent = ({
const [color, setColor] = useState(theme.colors.elevation.level2)
const [buttonPositions, setButtonPositions] = useState(generateRandomPositions())
const [timeoutId, setTimeoutId] = useState()
const hideModal = () => setVisible(false)
const [visible, setVisible] = React.useState(false)
const sharedStyle = useSharedStyles(theme)
const [wrongAnswers, setWrongAnswers] = useState(0)
const [wrongAnswerAlreadyAdded, setWrongAnswerAlreadyAdded] = useState([])
Expand All @@ -51,7 +46,7 @@ const WordsContent = ({

marginBottom: 10,
marginVertical: 10,
minHeight: 350
minHeight: 320
},
text: {
color: theme.colors.primary,
Expand Down Expand Up @@ -157,14 +152,6 @@ const WordsContent = ({
{ button: button3, position: buttonPositions[2] }
].sort((a, b) => a.position - b.position)

const details = (
<View>
{words[currentWord]?.grammar
? formatGrammar(words[currentWord].grammar, sharedStyle)
: 'No explanation available'}
</View>
)

const renderItem = ({ item }) => <View>{item.button}</View>

return (
Expand All @@ -181,35 +168,45 @@ const WordsContent = ({
style={{ height: 7, borderRadius: 10, backgroundColor: theme.colors.elevation.level2 }}
/>
<Surface style={styles.surface}>
<Text
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text
style={{
fontFamily: 'uthman',
width: '97%',
fontSize: 120,
textAlign: 'center',
color: theme.colors.secondary,
paddingBottom: 50
}}
>
{words[currentWord]?.arabic.trim()}
</Text>
</View>

{/* <Text
style={{
paddingTop: 15,
fontFamily: 'uthman',
width: '97%',
fontSize: 100,
...sharedStyle.arabicBody,
fontSize: 30,
textAlign: 'center',
color: theme.colors.secondary
paddingHorizontal: 10,
lineHeight: 45
}}
>
{words[currentWord]?.arabic.trim()}
</Text>

<Text style={{ ...sharedStyle.arabicBody, fontSize: 30, textAlign: 'center', paddingHorizontal: 30 }}>
{words[currentWord]?.arabicSentence}
</Text>
</Text> */}

<View style={{ position: 'absolute', bottom: 25, left: 10 }}>
{/* <View style={{ position: 'absolute', bottom: 15, left: 15, width: 130 }}>
<Text variant="labelSmall" style={{ color: theme.colors.outline }}>
{words[currentWord]?.source}
</Text>
</View>
</View> */}

<View style={{ position: 'absolute', bottom: 5, right: 10 }}>
<View style={{ flexDirection: 'row', position: 'absolute', bottom: 5, right: 10 }}>
<PlaySound
mode="text"
audioFileNames={[
`https://openarabic.ams3.digitaloceanspaces.com/audio/${words[currentWord].filename}`,
`https://openarabic.ams3.digitaloceanspaces.com/audio/${words[currentWord].filename}`,
`https://openarabic.ams3.digitaloceanspaces.com/audio/${words[currentWord].arabicSentenceFilename}`
`https://openarabic.ams3.digitaloceanspaces.com/audio/${words[currentWord].filename}`
]}
buttonText={'Play'}
style={{}}
Expand All @@ -222,12 +219,6 @@ const WordsContent = ({
duration={3500}
text="Session Completed Successfully!"
/>
<ModalScrollView
visible={visible}
content={details}
title={words[currentWord]?.arabic}
hideModal={hideModal}
/>
</>
}
/>
Expand Down
Loading