├── screenshot.png ├── src ├── paris.jpg ├── index.js ├── Components │ ├── Question.js │ ├── Answer.js │ ├── Stats.js │ ├── RevisionRow.js │ ├── Revision.js │ └── VerbDrillContainer.js ├── index.css └── registerServiceWorker.js ├── public ├── favicon.ico ├── sounds │ ├── oooooui.mp3 │ ├── voila.mp3 │ ├── cest-non.mp3 │ ├── exactement.mp3 │ ├── je-repond-non.mp3 │ └── oui-tres-bien.mp3 ├── manifest.json ├── index.html └── 404.html ├── database.rules.json ├── .firebaserc ├── .gitignore ├── firebase.json ├── package.json ├── README.md ├── LICENSE └── verbs.json /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/screenshot.png -------------------------------------------------------------------------------- /src/paris.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/src/paris.jpg -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/sounds/oooooui.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/sounds/oooooui.mp3 -------------------------------------------------------------------------------- /public/sounds/voila.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/sounds/voila.mp3 -------------------------------------------------------------------------------- /public/sounds/cest-non.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/sounds/cest-non.mp3 -------------------------------------------------------------------------------- /database.rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | ".read": "auth != null", 4 | ".write": "auth != null" 5 | } 6 | } -------------------------------------------------------------------------------- /public/sounds/exactement.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/sounds/exactement.mp3 -------------------------------------------------------------------------------- /public/sounds/je-repond-non.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/sounds/je-repond-non.mp3 -------------------------------------------------------------------------------- /public/sounds/oui-tres-bien.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewmcc/french-verbs/HEAD/public/sounds/oui-tres-bien.mp3 -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "firebase-frenchverbs", 4 | "production": "firebase-frenchverbs" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "database": { 3 | "rules": "database.rules.json" 4 | }, 5 | "hosting": { 6 | "public": "build", 7 | "ignore": [ 8 | "firebase.json", 9 | "**/.*", 10 | "**/node_modules/**" 11 | ], 12 | "rewrites": [ 13 | { 14 | "source": "**", 15 | "destination": "/index.html" 16 | } 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import 'bootstrap/dist/css/bootstrap.css' 4 | import './index.css' 5 | import VerbDrillContainer from './Components/VerbDrillContainer' 6 | import registerServiceWorker from './registerServiceWorker' 7 | 8 | ReactDOM.render(, document.getElementById('root')) 9 | registerServiceWorker() 10 | -------------------------------------------------------------------------------- /src/Components/Question.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Question extends Component { 4 | render() { 5 | return ( 6 |
7 |

{this.props.question.infinitive} - {this.props.question.tense}

8 |

{this.props.pronoun.english}

9 |
10 | ) 11 | } 12 | } 13 | 14 | Question.defaultProps = { 15 | question: '', 16 | pronoun: {} 17 | } 18 | 19 | export default Question 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "french-verbs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "MIT", 6 | "dependencies": { 7 | "babel-preset-react-app": "^3.1.0", 8 | "bootstrap": "^3.3.7", 9 | "firebase": "^4.5.0", 10 | "react": "^16.1.1", 11 | "react-dom": "^16.0.0", 12 | "react-scripts": "^1.0.14", 13 | "react-super-responsive-table": "^4.1.1" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test --env=jsdom", 19 | "eject": "react-scripts eject" 20 | }, 21 | "devDependencies": {} 22 | } 23 | -------------------------------------------------------------------------------- /src/Components/Answer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Answer extends Component { 4 | render() { 5 | return ( 6 |
7 |
8 |

{this.props.pronoun.pronoun}

9 | 10 | 11 | 12 |
13 |
14 | ) 15 | } 16 | } 17 | 18 | Answer.defaultProps = { 19 | question: '', 20 | pronoun: {} 21 | } 22 | 23 | export default Answer 24 | -------------------------------------------------------------------------------- /src/Components/Stats.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Stats extends Component { 4 | render() { 5 | let percentage; 6 | if(this.props.totalAnswered === 0) { 7 | percentage = 0; 8 | } else { 9 | percentage = Math.round((this.props.totalCorrect / this.props.totalAnswered) * 100); 10 | } 11 | return ( 12 |
13 |

{this.props.totalCorrect} / {this.props.totalAnswered} ({percentage}%)

14 |

Streak: {this.props.streak}

15 |
16 | ) 17 | } 18 | } 19 | 20 | Stats.defaultProps = { 21 | totalAnswered: 0, 22 | totalCorrect: 0, 23 | streak: 0 24 | } 25 | 26 | export default Stats 27 | -------------------------------------------------------------------------------- /src/Components/RevisionRow.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Tr, Td } from 'react-super-responsive-table' 3 | 4 | import 'react-super-responsive-table/dist/SuperResponsiveTableStyle.css' 5 | 6 | class RevisionRow extends Component { 7 | render() { 8 | let columns = []; 9 | for (let x = 0; x < this.props.data.tenses.length ; x++) { 10 | columns.push({this.props.data.tenses[x].pronouns[this.props.pronounIndex].answer}) 11 | } 12 | return ( 13 | 14 | {this.props.data.tenses[0].pronouns[this.props.pronounIndex].pronoun} 15 | {columns} 16 | 17 | ); 18 | } 19 | } 20 | 21 | RevisionRow.defaultProps = { 22 | data: [], 23 | pronounIndex: 0 24 | } 25 | 26 | export default RevisionRow 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # French Verb Drills 2 | 3 | ![Screenshot](screenshot.png) 4 | 5 | 6 | ## Available Scripts 7 | 8 | In the project directory, you can run: 9 | 10 | ### `npm start` 11 | 12 | Runs the app in the development mode.
13 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 14 | 15 | The page will reload if you make edits.
16 | You will also see any lint errors in the console. 17 | 18 | ### `npm test` 19 | 20 | Launches the test runner in the interactive watch mode.
21 | See the section about [running tests](#running-tests) for more information. 22 | 23 | ### `npm run build` 24 | 25 | Builds the app for production to the `build` folder.
26 | It correctly bundles React in production mode and optimizes the build for the best performance. 27 | 28 | The build is minified and the filenames include the hashes.
29 | Your app is ready to be deployed! 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Andrew McCafferty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Components/Revision.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Table, Thead, Tbody, Tr, Th } from 'react-super-responsive-table' 3 | import RevisionRow from './RevisionRow' 4 | 5 | import 'react-super-responsive-table/dist/SuperResponsiveTableStyle.css' 6 | 7 | 8 | class Revision extends Component { 9 | 10 | render() { 11 | 12 | let rows = []; 13 | this.props.data.tenses[0].pronouns.forEach((pronoun, id) => { 14 | rows.push() 15 | }); 16 | 17 | return ( 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {rows} 32 | 33 |
PronounPresentImparfaitPassé ComposéFuturConditionnel
34 |
35 | ); 36 | } 37 | } 38 | 39 | Revision.defaultProps = { 40 | data: [], 41 | showRevisionTable: false 42 | } 43 | 44 | export default Revision 45 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | French Verb Conjugator 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | font-family: helvetica, arial, sans-serif; 7 | background: #e8e8e8 url('paris.jpg') left top no-repeat; 8 | background-position: bottom; 9 | text-align: center; 10 | } 11 | 12 | .bold { 13 | font-weight: bold; 14 | } 15 | 16 | .col-centered { 17 | float: none; 18 | margin: 0 auto; 19 | } 20 | 21 | #question-card { 22 | background: #fff; 23 | margin: 30px auto 0 auto; 24 | padding: 0; 25 | text-align: center; 26 | opacity: 0.9; 27 | filter: alpha(opacity=90); /* For IE8 and earlier */ 28 | -webkit-border-radius: 2px !important; 29 | -moz-border-radius: 2px !important; 30 | border-radius: 2px !important; 31 | } 32 | 33 | #question-view { 34 | background: #0094FF; 35 | color: #fff; 36 | padding: 10px; 37 | opacity: 0.9; 38 | filter: alpha(opacity=90); /* For IE8 and earlier */ 39 | } 40 | 41 | #stats-view { 42 | background: #e7e6e6; 43 | padding: 10px; 44 | opacity: 0.9; 45 | filter: alpha(opacity=90); /* For IE8 and earlier */ 46 | } 47 | 48 | #stats-view .stats, #stats-view .streak { 49 | display: inline; 50 | } 51 | 52 | #stats-view .stats { 53 | margin-right: 15px; 54 | } 55 | 56 | h1 { 57 | margin: 30px 0 30px 0; 58 | } 59 | 60 | #question-card .pronoun p { 61 | font-size: 2em; 62 | margin-right: 10px; 63 | display: inline; 64 | } 65 | 66 | #question-view>p { 67 | font-size: 1.5em; 68 | margin-bottom: 15px; 69 | display: inline; 70 | } 71 | 72 | #question-card .pronoun p:first-letter { 73 | text-transform: uppercase; 74 | } 75 | 76 | #question-card input { 77 | font-size: 2em; 78 | margin: 30px 0 30px 0; 79 | padding: 3px; 80 | } 81 | 82 | #revision-view { 83 | background: #fff; 84 | margin: 15px auto 0 auto; 85 | padding: 15px; 86 | text-align: center; 87 | opacity: 0.9; 88 | filter: alpha(opacity=90); /* For IE8 and earlier */ 89 | } 90 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |
26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (!isLocalhost) { 36 | // Is not local host. Just register service worker 37 | registerValidSW(swUrl); 38 | } else { 39 | // This is running on localhost. Lets check if a service worker still exists or not. 40 | checkValidServiceWorker(swUrl); 41 | } 42 | }); 43 | } 44 | } 45 | 46 | function registerValidSW(swUrl) { 47 | navigator.serviceWorker 48 | .register(swUrl) 49 | .then(registration => { 50 | registration.onupdatefound = () => { 51 | const installingWorker = registration.installing; 52 | installingWorker.onstatechange = () => { 53 | if (installingWorker.state === 'installed') { 54 | if (navigator.serviceWorker.controller) { 55 | // At this point, the old content will have been purged and 56 | // the fresh content will have been added to the cache. 57 | // It's the perfect time to display a "New content is 58 | // available; please refresh." message in your web app. 59 | console.log('New content is available; please refresh.'); 60 | } else { 61 | // At this point, everything has been precached. 62 | // It's the perfect time to display a 63 | // "Content is cached for offline use." message. 64 | console.log('Content is cached for offline use.'); 65 | } 66 | } 67 | }; 68 | }; 69 | }) 70 | .catch(error => { 71 | console.error('Error during service worker registration:', error); 72 | }); 73 | } 74 | 75 | function checkValidServiceWorker(swUrl) { 76 | // Check if the service worker can be found. If it can't reload the page. 77 | fetch(swUrl) 78 | .then(response => { 79 | // Ensure service worker exists, and that we really are getting a JS file. 80 | if ( 81 | response.status === 404 || 82 | response.headers.get('content-type').indexOf('javascript') === -1 83 | ) { 84 | // No service worker found. Probably a different app. Reload the page. 85 | navigator.serviceWorker.ready.then(registration => { 86 | registration.unregister().then(() => { 87 | window.location.reload(); 88 | }); 89 | }); 90 | } else { 91 | // Service worker found. Proceed as normal. 92 | registerValidSW(swUrl); 93 | } 94 | }) 95 | .catch(() => { 96 | console.log( 97 | 'No internet connection found. App is running in offline mode.' 98 | ); 99 | }); 100 | } 101 | 102 | export function unregister() { 103 | if ('serviceWorker' in navigator) { 104 | navigator.serviceWorker.ready.then(registration => { 105 | registration.unregister(); 106 | }); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Components/VerbDrillContainer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import * as firebase from 'firebase' 3 | import Question from './Question' 4 | import Answer from './Answer' 5 | import Stats from './Stats' 6 | import Revision from './Revision' 7 | 8 | let audioContext; 9 | 10 | const firebaseConfig = { 11 | apiKey: "AIzaSyAyhciG0WcfP6ZAEdaGErDslc966XO2vus", 12 | authDomain: "frenchverbs.firebaseapp.com", 13 | databaseURL: "https://frenchverbs.firebaseio.com", 14 | projectId: "firebase-frenchverbs", 15 | storageBucket: "", 16 | messagingSenderId: "156765582776" 17 | }; 18 | 19 | class VerbDrillContainer extends Component { 20 | 21 | constructor(props) { 22 | super(props) 23 | 24 | this.state = { 25 | data: [], 26 | question: [], 27 | pronoun: {}, 28 | totalAnswered: 0, 29 | totalCorrect: 0, 30 | streak: 0, 31 | showRevision: false 32 | } 33 | 34 | this.checkAnswer = this.checkAnswer.bind(this) 35 | 36 | } 37 | 38 | componentWillMount() { 39 | 40 | window.AudioContext = window.AudioContext || window.webkitAudioContext 41 | audioContext = new window.AudioContext() 42 | 43 | firebase.initializeApp(firebaseConfig) 44 | firebase.database().ref('/verbs').once('value').then((snapshot) => { 45 | const question = this.getQuestion({verbs: snapshot.val()}) 46 | this.setState({ 47 | data: {verbs: snapshot.val()}, 48 | question 49 | }) 50 | }) 51 | } 52 | 53 | /* 54 | * Display the question, answer and stats components 55 | */ 56 | render() { 57 | return ( 58 |
59 |
60 |
61 | 62 | 63 | 64 |
65 |
66 | { this.state.showRevision && } 67 |
68 |
69 |
70 | ); 71 | } 72 | 73 | /* 74 | * Randomly select a new verb, tense and pronoun, and return a question object 75 | */ 76 | getQuestion(data) { 77 | const verbIndex = this.getRandomIndex(0, (data.verbs.length - 1)); 78 | const tenseIndex = this.getRandomIndex(0, (data.verbs[verbIndex].tenses.length - 1)); 79 | const pronounIndex = this.getRandomIndex(0, (data.verbs[verbIndex].tenses[tenseIndex].pronouns.length - 1)); 80 | const questionData = { 81 | 'infinitive': data.verbs[verbIndex].infinitive, 82 | 'translation': data.verbs[verbIndex].translation, 83 | 'tense': data.verbs[verbIndex].tenses[tenseIndex].name, 84 | 'pronoun': data.verbs[verbIndex].tenses[tenseIndex].pronouns[pronounIndex], 85 | 'revisionData': data.verbs[verbIndex] 86 | }; 87 | return questionData; 88 | } 89 | 90 | /* 91 | * Return a random integer with max and min. Used to select a question array index. 92 | */ 93 | getRandomIndex(min, max) { 94 | return Math.floor(Math.random() * (max - min + 1) + min); 95 | } 96 | 97 | /* 98 | * Check submitted answer against data, disregarding accents. 99 | */ 100 | checkAnswer(event) { 101 | event.preventDefault(); 102 | this.setState({ showRevision: false }); 103 | 104 | const answerWithoutAccents = this.foldAccents(this.state.question.pronoun.answer); 105 | const answer = this.state.question.pronoun.answer.toLowerCase(); 106 | const guess = event.target.guess.value.toLowerCase().trim(); 107 | 108 | if (guess === answer || guess === answerWithoutAccents) { 109 | this.randomPositiveSound(); 110 | this.setState({ totalAnswered: this.state.totalAnswered + 1, totalCorrect: this.state.totalCorrect + 1, streak: this.state.streak + 1, question: this.getQuestion(this.state.data) }); 111 | event.target.guess.value = ''; 112 | } else { 113 | this.randomNegativeSound(); 114 | event.target.guess.value = ''; 115 | this.setState({ streak: 0, totalAnswered: this.state.totalAnswered + 1, showRevision: true }); 116 | } 117 | } 118 | 119 | /* 120 | * Substitute accented characters in a string 121 | */ 122 | foldAccents(inputString) { 123 | const accentMap = {'á':'a', 'é':'e', 'ê':'e', 'í':'i', 'î':'i', 'ó':'o','ú':'u'}; 124 | if (!inputString) { return ''; } 125 | let returnString = ''; 126 | for (let i = 0; i < inputString.length; i++) { 127 | returnString += accentMap[inputString.charAt(i)] || inputString.charAt(i); 128 | } 129 | return returnString; 130 | } 131 | 132 | capitalisePronouns(data) { 133 | data.verbs.forEach((verb, verbId) => { 134 | verb.tenses.forEach((tense, tenseId) => { 135 | tense.pronouns.forEach((pronoun, pronounId) => { 136 | data.verbs[verbId].tenses[tenseId].pronouns[pronounId].pronoun = this.capitalise(data.verbs[verbId].tenses[tenseId].pronouns[pronounId].pronoun); 137 | }); 138 | }); 139 | }); 140 | return data; 141 | } 142 | 143 | capitalise(s) { 144 | return s[0].toUpperCase() + s.slice(1); 145 | } 146 | 147 | /* 148 | * Hack to unlock HTML5 Audio on iOS 149 | */ 150 | handleTouchEnd() { 151 | const buffer = audioContext.createBuffer(1, 1, 22050); 152 | const sourceBuffer = audioContext.createBufferSource(); 153 | sourceBuffer.buffer = buffer; 154 | sourceBuffer.connect(audioContext.destination); 155 | sourceBuffer.start(audioContext.currentTime); 156 | //sourceBuffer.noteOn(0); 157 | } 158 | 159 | playSound(buffer) { 160 | const sourceBuffer = audioContext.createBufferSource(); 161 | sourceBuffer.buffer = buffer; 162 | sourceBuffer.connect(audioContext.destination); 163 | sourceBuffer.start(audioContext.currentTime); 164 | } 165 | 166 | loadSound(file) { 167 | const request = new XMLHttpRequest(); 168 | request.open('GET', file, true); 169 | request.responseType = 'arraybuffer'; 170 | request.onload = () => { 171 | audioContext.decodeAudioData(request.response, (buffer) => { 172 | this.playSound(buffer); 173 | }); 174 | }; 175 | request.send(); 176 | } 177 | 178 | randomPositiveSound() { 179 | const positives = ['sounds/oooooui.mp3', 'sounds/oui-tres-bien.mp3', 'sounds/voila.mp3', 'sounds/exactement.mp3']; 180 | this.loadSound(positives[Math.floor(Math.random() * positives.length)]); 181 | } 182 | 183 | randomNegativeSound() { 184 | const negatives = ['sounds/cest-non.mp3', 'sounds/je-repond-non.mp3']; 185 | this.loadSound(negatives[Math.floor(Math.random() * negatives.length)]); 186 | } 187 | 188 | } 189 | 190 | export default VerbDrillContainer 191 | -------------------------------------------------------------------------------- /verbs.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbs": [ 3 | { 4 | "infinitive": "être", 5 | "translation": "To be", 6 | "tenses": [ 7 | { 8 | "name": "présent", 9 | "pronouns": [ 10 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "suis", "english": "I am"}, 11 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "es", "english": "You are"}, 12 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "est", "english": "He/she/one is"}, 13 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "sommes", "english": "We are"}, 14 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "êtes", "english": "You are"}, 15 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "sont", "english": "They are"} 16 | ] 17 | }, 18 | { 19 | "name": "imparfait", 20 | "pronouns": [ 21 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "étais", "english": "I was"}, 22 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "étais", "english": "You were"}, 23 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "était", "english": "He/she/one was"}, 24 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "étions", "english": "We were"}, 25 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "étiez", "english": "You were"}, 26 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "étaient", "english": "They were"} 27 | ] 28 | }, 29 | { 30 | "name": "passé composé", 31 | "pronouns": [ 32 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai été", "english": "I have been"}, 33 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as été", "english": "You have been"}, 34 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a été", "english": "He/she/one has been"}, 35 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons été", "english": "We have been"}, 36 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez été", "english": "You have been"}, 37 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont été", "english": "They have been"} 38 | ] 39 | }, 40 | { 41 | "name": "futur", 42 | "pronouns": [ 43 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "serai", "english": "I will be"}, 44 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "seras", "english": "You will be"}, 45 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "sera", "english": "He/she/one will be"}, 46 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "serons", "english": "We will be"}, 47 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "serez", "english": "You will be"}, 48 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "seront", "english": "They will be"} 49 | ] 50 | }, 51 | { 52 | "name": "conditionnel", 53 | "pronouns": [ 54 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "serais", "english": "I would be"}, 55 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "serais", "english": "You would be"}, 56 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "serait", "english": "He/she/one would be"}, 57 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "serions", "english": "We would be"}, 58 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "seriez", "english": "You would be"}, 59 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "seraient", "english": "They would be"} 60 | ] 61 | }] 62 | }, 63 | { 64 | "infinitive": "avoir", 65 | "translation": "To have", 66 | "tenses": [ 67 | { 68 | "name": "présent", 69 | "pronouns": [ 70 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai", "english": "I have"}, 71 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as", "english": "You have"}, 72 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a", "english": "He/she/one has"}, 73 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons", "english": "We have"}, 74 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez", "english": "You have"}, 75 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont", "english": "They have"} 76 | ] 77 | }, 78 | { 79 | "name": "imparfait", 80 | "pronouns": [ 81 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "avais", "english": "I had"}, 82 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "avais", "english": "You had"}, 83 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "avait", "english": "He/she/one had"}, 84 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avions", "english": "We had"}, 85 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "aviez", "english": "You had"}, 86 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "avaient", "english": "They had"} 87 | ] 88 | }, 89 | { 90 | "name": "passé composé", 91 | "pronouns": [ 92 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai eu", "english": "I have had"}, 93 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as eu", "english": "You have had"}, 94 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a eu", "english": "He/she/one has had"}, 95 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons eu", "english": "We have had"}, 96 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez eu", "english": "You have had"}, 97 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont eu", "english": "They have had"} 98 | ] 99 | }, 100 | { 101 | "name": "futur", 102 | "pronouns": [ 103 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "aurai", "english": "I will have"}, 104 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "auras", "english": "You will have"}, 105 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "aura", "english": "He/she/one will have"}, 106 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "aurons", "english": "We will have"}, 107 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "aurez", "english": "You will have"}, 108 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "auront", "english": "They will have"} 109 | ] 110 | }, 111 | { 112 | "name": "conditionnel", 113 | "pronouns": [ 114 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "aurais", "english": "I would have"}, 115 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "aurais", "english": "You would have"}, 116 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "aurait", "english": "He/she/one would have"}, 117 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "aurions", "english": "We would have"}, 118 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "auriez", "english": "You would have"}, 119 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "auraient", "english": "They would have"} 120 | ] 121 | }] 122 | }, 123 | { 124 | "infinitive": "aller", 125 | "translation": "To go", 126 | "tenses": [ 127 | { 128 | "name": "présent", 129 | "pronouns": [ 130 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "vais", "english": "I go"}, 131 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "vas", "english": "You go"}, 132 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "va", "english": "He/she/one go"}, 133 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "allons", "english": "We go"}, 134 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "allez", "english": "You go"}, 135 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "vont", "english": "They go"} 136 | ] 137 | }, 138 | { 139 | "name": "imparfait", 140 | "pronouns": [ 141 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "allais", "english": "I went"}, 142 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "allais", "english": "You went"}, 143 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "allait", "english": "He/she/one went"}, 144 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "allions", "english": "We went"}, 145 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "alliez", "english": "You went"}, 146 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "allaient", "english": "They went"} 147 | ] 148 | }, 149 | { 150 | "name": "passé composé", 151 | "pronouns": [ 152 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "suis allé", "english": "I have gone"}, 153 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "es allé", "english": "You have gone"}, 154 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "est allé", "english": "He/she/one has gone"}, 155 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "sommes allé", "english": "We have gone"}, 156 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "êtes allé", "english": "You have gone"}, 157 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "sont allés", "english": "They have gone"} 158 | ] 159 | }, 160 | { 161 | "name": "futur", 162 | "pronouns": [ 163 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "irai", "english": "I will go"}, 164 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "iras", "english": "You will go"}, 165 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "ira", "english": "He/she/one will go"}, 166 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "irons", "english": "We will go"}, 167 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "irez", "english": "You will go"}, 168 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "iront", "english": "They will go"} 169 | ] 170 | }, 171 | { 172 | "name": "conditionnel", 173 | "pronouns": [ 174 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "irais", "english": "I would go"}, 175 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "irais", "english": "You would go"}, 176 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "irait", "english": "He/she/one would go"}, 177 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "irions", "english": "We would go"}, 178 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "iriez", "english": "You would go"}, 179 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "iraient", "english": "They would go"} 180 | ] 181 | }] 182 | }, 183 | { 184 | "infinitive": "faire", 185 | "translation": "To make / To do", 186 | "tenses": [ 187 | { 188 | "name": "présent", 189 | "pronouns": [ 190 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "fais", "english": "I make/do"}, 191 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "fais", "english": "You make/do"}, 192 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "fait", "english": "He/she/one makes/does"}, 193 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "faisons", "english": "We make/do"}, 194 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "faites", "english": "You make/do"}, 195 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "font", "english": "They make/do"} 196 | ] 197 | }, 198 | { 199 | "name": "imparfait", 200 | "pronouns": [ 201 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "faisais", "english": "I made/did"}, 202 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "faisais", "english": "You made/did"}, 203 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "faisait", "english": "He/she/one made/did"}, 204 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "faisions", "english": "We made/did"}, 205 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "faisiez", "english": "You made/did"}, 206 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "faisaient", "english": "They made/did"} 207 | ] 208 | }, 209 | { 210 | "name": "passé composé", 211 | "pronouns": [ 212 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai fait", "english": "I have made/done"}, 213 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as fait", "english": "You have made/done"}, 214 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a fait", "english": "He/she/one has made/done"}, 215 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons fait", "english": "We have made/done"}, 216 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez fait", "english": "You have made/done"}, 217 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont fait", "english": "They have made/done"} 218 | ] 219 | }, 220 | { 221 | "name": "futur", 222 | "pronouns": [ 223 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "ferai", "english": "I will make/do"}, 224 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "feras", "english": "You will make/do"}, 225 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "fera", "english": "He/she/one will make/do"}, 226 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "ferons", "english": "We will make/do"}, 227 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "ferez", "english": "You will make/do"}, 228 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "feront", "english": "They will make/do"} 229 | ] 230 | }, 231 | { 232 | "name": "conditionnel", 233 | "pronouns": [ 234 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "ferais", "english": "I would make/do"}, 235 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "ferais", "english": "You would make/do"}, 236 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "ferait", "english": "He/she/one would make/do"}, 237 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "ferions", "english": "We would make/do"}, 238 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "feriez", "english": "You would make/do"}, 239 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "feraient", "english": "They would make/do"} 240 | ] 241 | }] 242 | }, 243 | { 244 | "infinitive": "savoir", 245 | "translation": "To know", 246 | "tenses": [ 247 | { 248 | "name": "présent", 249 | "pronouns": [ 250 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "sais", "english": "I know"}, 251 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "sais", "english": "You know"}, 252 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "sait", "english": "He/she/one knows"}, 253 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "savons", "english": "We know"}, 254 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "savez", "english": "You know"}, 255 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "savent", "english": "They know"} 256 | ] 257 | }, 258 | { 259 | "name": "imparfait", 260 | "pronouns": [ 261 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "savais", "english": "I knew"}, 262 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "savais", "english": "You knew"}, 263 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "savait", "english": "He/she/one knew"}, 264 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "savions", "english": "We knew"}, 265 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "saviez", "english": "You knew"}, 266 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "savaient", "english": "They knew"} 267 | ] 268 | }, 269 | { 270 | "name": "passé composé", 271 | "pronouns": [ 272 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai su", "english": "I have known"}, 273 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as su", "english": "You have known"}, 274 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a su", "english": "He/she/one has known"}, 275 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons su", "english": "We have known"}, 276 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez su", "english": "You have known"}, 277 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont su", "english": "They have known"} 278 | ] 279 | }, 280 | { 281 | "name": "futur", 282 | "pronouns": [ 283 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "saurai", "english": "I will know"}, 284 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "sauras", "english": "You will know"}, 285 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "saura", "english": "He/she/one will know"}, 286 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "saurons", "english": "We will know"}, 287 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "saurez", "english": "You will know"}, 288 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "sauront", "english": "They will know"} 289 | ] 290 | }, 291 | { 292 | "name": "conditionnel", 293 | "pronouns": [ 294 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "saurais", "english": "I would know"}, 295 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "saurais", "english": "You would know"}, 296 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "saurait", "english": "He/she/one would know"}, 297 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "saurions", "english": "We would know"}, 298 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "sauriez", "english": "You would know"}, 299 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "sauraient", "english": "They would know"} 300 | ] 301 | }] 302 | }, 303 | { 304 | "infinitive": "voir", 305 | "translation": "To see", 306 | "tenses": [ 307 | { 308 | "name": "présent", 309 | "pronouns": [ 310 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "vois", "english": "I see"}, 311 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "vois", "english": "You see"}, 312 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "voit", "english": "He/she/one sees"}, 313 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "voyons", "english": "We see"}, 314 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "voyez", "english": "You see"}, 315 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "voient", "english": "They see"} 316 | ] 317 | }, 318 | { 319 | "name": "imparfait", 320 | "pronouns": [ 321 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "voyais", "english": "I saw"}, 322 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "voyais", "english": "You saw"}, 323 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "voyait", "english": "He/she/one saw"}, 324 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "voyions", "english": "We saw"}, 325 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "voyiez", "english": "You saw"}, 326 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "voyaient", "english": "They saw"} 327 | ] 328 | }, 329 | { 330 | "name": "passé composé", 331 | "pronouns": [ 332 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai vu", "english": "I have seen"}, 333 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as vu", "english": "You have seen"}, 334 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a vu", "english": "He/she/one has seen"}, 335 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons vu", "english": "We have seen"}, 336 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez vu", "english": "You have seen"}, 337 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont vu", "english": "They have seen"} 338 | ] 339 | }, 340 | { 341 | "name": "futur", 342 | "pronouns": [ 343 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "verrai", "english": "I will see"}, 344 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "verras", "english": "You will see"}, 345 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "verra", "english": "He/she/one will see"}, 346 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "verrons", "english": "We will see"}, 347 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "verrez", "english": "You will see"}, 348 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "verront", "english": "They will see"} 349 | ] 350 | }, 351 | { 352 | "name": "conditionnel", 353 | "pronouns": [ 354 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "verrais", "english": "I would see"}, 355 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "verrais", "english": "You would see"}, 356 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "verrait", "english": "He/she/one would see"}, 357 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "verrions", "english": "We would see"}, 358 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "verriez", "english": "You would see"}, 359 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "verraient", "english": "They would see"} 360 | ] 361 | }] 362 | }, 363 | { 364 | "infinitive": "mettre", 365 | "translation": "To put", 366 | "tenses": [ 367 | { 368 | "name": "présent", 369 | "pronouns": [ 370 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "mets", "english": "I put"}, 371 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "mets", "english": "You put"}, 372 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "met", "english": "He/she/one puts"}, 373 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "mettons", "english": "We put"}, 374 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "mettez", "english": "You put"}, 375 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "mettent", "english": "They put"} 376 | ] 377 | }, 378 | { 379 | "name": "imparfait", 380 | "pronouns": [ 381 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "mettais", "english": "I put"}, 382 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "mettais", "english": "You put"}, 383 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "mettait", "english": "He/she/one put"}, 384 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "mettions", "english": "We put"}, 385 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "mettiez", "english": "You put"}, 386 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "mettaient", "english": "They put"} 387 | ] 388 | }, 389 | { 390 | "name": "passé composé", 391 | "pronouns": [ 392 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai mis", "english": "I have put"}, 393 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as mis", "english": "You have put"}, 394 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a mis", "english": "He/she/one has put"}, 395 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons mis", "english": "We have put"}, 396 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez mis", "english": "You have put"}, 397 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont mis", "english": "They have put"} 398 | ] 399 | }, 400 | { 401 | "name": "futur", 402 | "pronouns": [ 403 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "mettrai", "english": "I will put"}, 404 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "mettras", "english": "You will put"}, 405 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "mettra", "english": "He/she/one will put"}, 406 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "mettrons", "english": "We will put"}, 407 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "mettrez", "english": "You will put"}, 408 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "mettront", "english": "They will put"} 409 | ] 410 | }, 411 | { 412 | "name": "conditionnel", 413 | "pronouns": [ 414 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "mettrais", "english": "I would put"}, 415 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "mettrais", "english": "You would put"}, 416 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "mettrait", "english": "He/she/one would put"}, 417 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "mettrions", "english": "We would put"}, 418 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "mettriez", "english": "You would put"}, 419 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "mettraient", "english": "They would put"} 420 | ] 421 | }] 422 | }, 423 | { 424 | "infinitive": "connaitre", 425 | "translation": "To know (someone)", 426 | "tenses": [ 427 | { 428 | "name": "présent", 429 | "pronouns": [ 430 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "connaits", "english": "I know"}, 431 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "connaits", "english": "You know"}, 432 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "connait", "english": "He/she/one knows"}, 433 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "connaitons", "english": "We know"}, 434 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "connaitez", "english": "You know"}, 435 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "connaitent", "english": "They know"} 436 | ] 437 | }, 438 | { 439 | "name": "imparfait", 440 | "pronouns": [ 441 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "connaitais", "english": "I knew"}, 442 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "connaitais", "english": "You knew"}, 443 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "connaitait", "english": "He/she/one knew"}, 444 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "connaitions", "english": "We knew"}, 445 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "connaitiez", "english": "You knew"}, 446 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "connaitaient", "english": "They knew"} 447 | ] 448 | }, 449 | { 450 | "name": "passé composé", 451 | "pronouns": [ 452 | {"name": "firstPersonSingular", "pronoun": "j'", "answer": "ai connaitu", "english": "I have known"}, 453 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "as connaitu", "english": "You have known"}, 454 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "a connaitu", "english": "He/she/one has known"}, 455 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "avons connaitu", "english": "We have known"}, 456 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "avez connaitu", "english": "You have known"}, 457 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "ont connaitu", "english": "They have known"} 458 | ] 459 | }, 460 | { 461 | "name": "futur", 462 | "pronouns": [ 463 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "connaitrai", "english": "I will know"}, 464 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "connaitras", "english": "You will know"}, 465 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "connaitra", "english": "He/she/one will know"}, 466 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "connaitrons", "english": "We will know"}, 467 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "connaitrez", "english": "You will know"}, 468 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "connaitront", "english": "They will know"} 469 | ] 470 | }, 471 | { 472 | "name": "conditionnel", 473 | "pronouns": [ 474 | {"name": "firstPersonSingular", "pronoun": "je", "answer": "connaitrais", "english": "I would know"}, 475 | {"name": "secondPersonSingular", "pronoun": "tu", "answer": "connaitrais", "english": "You would know"}, 476 | {"name": "thirdPersonSingular", "pronoun": "il/elle/on", "answer": "connaitrait", "english": "He/she/one would know"}, 477 | {"name": "firstPersonPlural", "pronoun": "nous", "answer": "connaitrions", "english": "We would know"}, 478 | {"name": "secondPersonPlural", "pronoun": "vous", "answer": "connaitriez", "english": "You would know"}, 479 | {"name": "thirdPersonPlural", "pronoun": "ils/elles", "answer": "connaitraient", "english": "They would know"} 480 | ] 481 | }] 482 | } 483 | ]} --------------------------------------------------------------------------------