Skip to content
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
215 changes: 215 additions & 0 deletions src/plays/language-translater/LanguageTranslater.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
import PlayHeader from 'common/playlists/PlayHeader';
import './styles.css';
import { useEffect, useState } from 'react';
import languages from './Languages';
import copy from './icons/Copy.svg';
import sound from './icons/sound_max_fill.svg';
import { debounce } from 'lodash';
import switchLang from './icons/Horizontal_top_left_main.svg';

// WARNING: Do not change the entry componenet name
function LanguageTranslater(props) {
const [inputText, setInputText] = useState('Hello, How are you?'); // set input text for initial render
const [translatedText, setTranslatedText] = useState('');
const [sourceLang, setSourceLang] = useState('Autodetect'); // set initial sourceLang to Autodetect
const [targetLang, setTargetLang] = useState('fr'); // set initial targetLang to french

// used useEffect to translation during initial render
useEffect(() => {
translate();
}, []);

// fetching the data from API
const translate = async () => {
try {
const response = await fetch(
`https://api.mymemory.translated.net/get?q=${encodeURIComponent(inputText)}!&langpair=${sourceLang}|${targetLang}`
);
const data = await response.json();
setTranslatedText(data.responseData.translatedText);
} catch (err) {
window.alert('Error translating text:', err);
}
};

// used debounce for limiting the rate at which the translation function is called
const debouncedTranslate = debounce(translate, 300);

// function for initializing translation
const handleTranslate = () => {
debouncedTranslate();
};

// function to switch source and target languages
const switchLanguage = () => {
if (sourceLang !== 'Autodetect') {
const temp = sourceLang;
setSourceLang(targetLang);
setTargetLang(temp);
} else {
window.alert('Cannot switch language when source language is Autodetect');
}
};

// clipboard copy function
const handleCopy = (text) => {
navigator.clipboard.writeText(text);
};

// text to speech function
const handleListen = async (text, language) => {
try {
const utterence = new SpeechSynthesisUtterance(text);
utterence.language = language;
await window.speechSynthesis.speak(utterence);
} catch (err) {
window.alert(`Listening error: `, err);
}
};

return (
<>
<div className="play-details">
<PlayHeader play={props} />
<div className="play-details-body Language-Translator_body">
{/* Your Code Starts Here */}
<div>
<div className="Language-Translator_container">
<div className="Language-Translator_sourceLang">
<section className="Language-Translator_languages">
<button
className={`Language-Translator_langButtons ${sourceLang === 'Autodetect' ? 'selected' : ''}`}
value="Autodetect"
onClick={(e) => setSourceLang(e.target.value)}
>
Detect Language
</button>
<button
className={`Language-Translator_langButtons ${sourceLang === 'en' ? 'selected' : ''}`}
value="en"
onClick={(e) => setSourceLang(e.target.value)}
>
English
</button>
<button
className={`Language-Translator_langButtons ${sourceLang === 'fr' ? 'selected' : ''}`}
value="fr"
onClick={(e) => setSourceLang(e.target.value)}
>
French
</button>
<select
className="Language-Translator_langSelectBtn"
name="languages"
value={sourceLang}
onChange={(e) => setSourceLang(e.target.value)}
>
{languages.map((lang) => (
<option key={lang.code} value={lang.code}>
{lang.name}
</option>
))}
</select>
</section>
<section className="Language-Translator_textbox">
<textarea
className="Language-Translator_textarea"
maxLength={500}
rows={10}
value={inputText}
onChange={(e) => setInputText(e.target.value)}
/>
<div className="Language-Translator_wordCount">{inputText.length}/500</div>
</section>
<section className="Language-Translator_buttons">
<div className="Language-Translator_imgBtns">
<img
alt="copy svg"
className="Language-Translator_img"
src={copy}
onClick={() => handleCopy(inputText)}
/>
<img
alt="sound svg"
className="Language-Translator_img"
src={sound}
onClick={() => handleListen(inputText, sourceLang)}
/>
</div>
<div className="Language-Translator_translateBtn" onClick={handleTranslate}>
Translate
</div>
</section>
</div>
<div className="Language-Translator_targetLang">
<section className="Language-Translator_languages">
<button
className={`Language-Translator_langButtons ${targetLang === 'en' ? 'selected' : ''}`}
value="en"
onClick={(e) => setTargetLang(e.target.value)}
>
English
</button>
<button
className={`Language-Translator_langButtons ${targetLang === 'fr' ? 'selected' : ''}`}
value="fr"
onClick={(e) => setTargetLang(e.target.value)}
>
French
</button>
<select
className="Language-Translator_langSelectBtn"
name="languages"
value={targetLang}
onChange={(e) => setTargetLang(e.target.value)}
>
{languages.map((lang) => (
<option key={lang.code} value={lang.code}>
{lang.name}
</option>
))}
</select>
<img
alt="switch Btn"
className="Language-Translator_img"
src={switchLang}
onClick={switchLanguage}
/>
</section>
<section className="Language-Translator_textbox">
<textarea
readOnly
className="Language-Translator_textarea"
maxLength={500}
rows={10}
value={translatedText}
/>
<div className="Language-Translator_wordCount">{translatedText.length}/500</div>
</section>
<section className="Language-Translator_buttons">
<div className="Language-Translator_imgBtns">
<img
alt="copy svg"
className="Language-Translator_img"
src={copy}
onClick={() => handleCopy(translatedText)}
/>
<img
alt="sound svg"
className="Language-Translator_img"
src={sound}
onClick={() => handleListen(translatedText, targetLang)}
/>
</div>
</section>
</div>
</div>
</div>
{/* Your Code Ends Here */}
</div>
</div>
</>
);
}

export default LanguageTranslater;
156 changes: 156 additions & 0 deletions src/plays/language-translater/Languages.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// initializing a array of languages and their respective language_codes
const languages = [
{ code: 'af-ZA', name: 'Afrikaans' },
{ code: 'sq-AL', name: 'Albanian' },
{ code: 'am-ET', name: 'Amharic' },
{ code: 'ar-SA', name: 'Arabic' },
{ code: 'hy-AM', name: 'Armenian' },
{ code: 'az-AZ', name: 'Azerbaijani' },
{ code: 'bjs-BB', name: 'Bajan' },
{ code: 'rm-RO', name: 'Balkan Gipsy' },
{ code: 'eu-ES', name: 'Basque' },
{ code: 'bem-ZM', name: 'Bemba' },
{ code: 'bn-IN', name: 'Bengali' },
{ code: 'be-BY', name: 'Belarus' },
{ code: 'bi-VU', name: 'Bislama' },
{ code: 'bs-BA', name: 'Bosnian' },
{ code: 'br-FR', name: 'Breton' },
{ code: 'bg-BG', name: 'Bulgarian' },
{ code: 'my-MM', name: 'Burmese' },
{ code: 'ca-ES', name: 'Catalan' },
{ code: 'ceb-PH', name: 'Cebuano' },
{ code: 'ch-GU', name: 'Chamorro' },
{ code: 'zh-CN', name: 'Chinese (Simplified)' },
{ code: 'zh-TW', name: 'Chinese Traditional' },
{ code: 'zdj-KM', name: 'Comorian (Ngazidja)' },
{ code: 'cop-EG', name: 'Coptic' },
{ code: 'aig-AG', name: 'Creole English (Antigua and Barbuda)' },
{ code: 'bah-BS', name: 'Creole English (Bahamas)' },
{ code: 'gcl-GD', name: 'Creole English (Grenadian)' },
{ code: 'gyn-GY', name: 'Creole English (Guyanese)' },
{ code: 'jam-JM', name: 'Creole English (Jamaican)' },
{ code: 'svc-VC', name: 'Creole English (Vincentian)' },
{ code: 'vic-US', name: 'Creole English (Virgin Islands)' },
{ code: 'ht-HT', name: 'Creole French (Haitian)' },
{ code: 'acf-LC', name: 'Creole French (Saint Lucian)' },
{ code: 'crs-SC', name: 'Creole French (Seselwa)' },
{ code: 'pov-GW', name: 'Creole Portuguese (Upper Guinea)' },
{ code: 'hr-HR', name: 'Croatian' },
{ code: 'cs-CZ', name: 'Czech' },
{ code: 'da-DK', name: 'Danish' },
{ code: 'nl-NL', name: 'Dutch' },
{ code: 'dz-BT', name: 'Dzongkha' },
{ code: 'en-GB', name: 'English' },
{ code: 'eo-EU', name: 'Esperanto' },
{ code: 'et-EE', name: 'Estonian' },
{ code: 'fn-FNG', name: 'Fanagalo' },
{ code: 'fo-FO', name: 'Faroese' },
{ code: 'fi-FI', name: 'Finnish' },
{ code: 'fr-FR', name: 'French' },
{ code: 'gl-ES', name: 'Galician' },
{ code: 'ka-GE', name: 'Georgian' },
{ code: 'de-DE', name: 'German' },
{ code: 'el-GR', name: 'Greek' },
{ code: 'grc-GR', name: 'Greek (Classical)' },
{ code: 'gu-IN', name: 'Gujarati' },
{ code: 'ha-NE', name: 'Hausa' },
{ code: 'haw-US', name: 'Hawaiian' },
{ code: 'he-IL', name: 'Hebrew' },
{ code: 'hi-IN', name: 'Hindi' },
{ code: 'hu-HU', name: 'Hungarian' },
{ code: 'is-IS', name: 'Icelandic' },
{ code: 'id-ID', name: 'Indonesian' },
{ code: 'kl-GL', name: 'Inuktitut (Greenlandic)' },
{ code: 'ga-IE', name: 'Irish Gaelic' },
{ code: 'it-IT', name: 'Italian' },
{ code: 'ja-JP', name: 'Japanese' },
{ code: 'jv-ID', name: 'Javanese' },
{ code: 'kea-CV', name: 'Kabuverdianu' },
{ code: 'kab-DZ', name: 'Kabylian' },
{ code: 'kn-IN', name: 'Kannada' },
{ code: 'kk-KZ', name: 'Kazakh' },
{ code: 'km-KM', name: 'Khmer' },
{ code: 'rw-RW', name: 'Kinyarwanda' },
{ code: 'rn-BI', name: 'Kirundi' },
{ code: 'ko-KR', name: 'Korean' },
{ code: 'ku-TR', name: 'Kurdish' },
{ code: 'ckb-IQ', name: 'Kurdish Sorani' },
{ code: 'ky-KG', name: 'Kyrgyz' },
{ code: 'lo-LA', name: 'Lao' },
{ code: 'la-VA', name: 'Latin' },
{ code: 'lv-LV', name: 'Latvian' },
{ code: 'lt-LT', name: 'Lithuanian' },
{ code: 'lb-LU', name: 'Luxembourgish' },
{ code: 'mk-MK', name: 'Macedonian' },
{ code: 'mg-MG', name: 'Malagasy' },
{ code: 'ms-MY', name: 'Malay' },
{ code: 'dv-MV', name: 'Maldivian' },
{ code: 'mt-MT', name: 'Maltese' },
{ code: 'gv-IM', name: 'Manx Gaelic' },
{ code: 'mi-NZ', name: 'Maori' },
{ code: 'mh-MH', name: 'Marshallese' },
{ code: 'men-SL', name: 'Mende' },
{ code: 'mn-MN', name: 'Mongolian' },
{ code: 'mfe-MU', name: 'Morisyen' },
{ code: 'ne-NP', name: 'Nepali' },
{ code: 'niu-NU', name: 'Niuean' },
{ code: 'no-NO', name: 'Norwegian' },
{ code: 'ny-MW', name: 'Nyanja' },
{ code: 'ur-PK', name: 'Pakistani' },
{ code: 'pau-PW', name: 'Palauan' },
{ code: 'pa-IN', name: 'Panjabi' },
{ code: 'pap-CW', name: 'Papiamentu' },
{ code: 'ps-PK', name: 'Pashto' },
{ code: 'fa-IR', name: 'Persian' },
{ code: 'pis-SB', name: 'Pijin' },
{ code: 'pl-PL', name: 'Polish' },
{ code: 'pt-PT', name: 'Portuguese' },
{ code: 'pot-US', name: 'Potawatomi' },
{ code: 'qu-PE', name: 'Quechua' },
{ code: 'ro-RO', name: 'Romanian' },
{ code: 'ru-RU', name: 'Russian' },
{ code: 'sm-WS', name: 'Samoan' },
{ code: 'sg-CF', name: 'Sango' },
{ code: 'gd-GB', name: 'Scots Gaelic' },
{ code: 'sr-RS', name: 'Serbian' },
{ code: 'sn-ZW', name: 'Shona' },
{ code: 'si-LK', name: 'Sinhala' },
{ code: 'sk-SK', name: 'Slovak' },
{ code: 'sl-SI', name: 'Slovenian' },
{ code: 'so-SO', name: 'Somali' },
{ code: 'st-ST', name: 'Sotho, Southern' },
{ code: 'es-ES', name: 'Spanish' },
{ code: 'srn-SR', name: 'Sranan Tongo' },
{ code: 'sw-SZ', name: 'Swahili' },
{ code: 'sv-SE', name: 'Swedish' },
{ code: 'de-CH', name: 'Swiss German' },
{ code: 'syc-TR', name: 'Syriac (Aramaic)' },
{ code: 'tl-PH', name: 'Tagalog' },
{ code: 'tg-TJ', name: 'Tajik' },
{ code: 'tmh-DZ', name: 'Tamashek (Tuareg)' },
{ code: 'ta-LK', name: 'Tamil' },
{ code: 'te-IN', name: 'Telugu' },
{ code: 'tet-TL', name: 'Tetum' },
{ code: 'th-TH', name: 'Thai' },
{ code: 'bo-CN', name: 'Tibetan' },
{ code: 'ti-TI', name: 'Tigrinya' },
{ code: 'tpi-PG', name: 'Tok Pisin' },
{ code: 'tkl-TK', name: 'Tokelauan' },
{ code: 'to-TO', name: 'Tongan' },
{ code: 'tn-BW', name: 'Tswana' },
{ code: 'tr-TR', name: 'Turkish' },
{ code: 'tk-TM', name: 'Turkmen' },
{ code: 'tvl-TV', name: 'Tuvaluan' },
{ code: 'uk-UA', name: 'Ukrainian' },
{ code: 'ppk-ID', name: 'Uma' },
{ code: 'uz-UZ', name: 'Uzbek' },
{ code: 'vi-VN', name: 'Vietnamese' },
{ code: 'wls-WF', name: 'Wallisian' },
{ code: 'cy-GB', name: 'Welsh' },
{ code: 'wo-SN', name: 'Wolof' },
{ code: 'xh-ZA', name: 'Xhosa' },
{ code: 'yi-YD', name: 'Yiddish' },
{ code: 'zu-ZA', name: 'Zulu' }
];

export default languages;
Loading