Skip to content

Commit

Permalink
Add word status
Browse files Browse the repository at this point in the history
  • Loading branch information
sonic16x committed Nov 24, 2024
1 parent 654aa12 commit 2a3e7a7
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 18 deletions.
7 changes: 7 additions & 0 deletions src/components/Modals/TranslationsModal/TranslationsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useModalDialog } from 'hooks/useModalDialog';
import { useResults } from 'hooks/useResults';
import { getCyrillic } from 'utils/getCyrillic';
import { getLatin } from 'utils/getLatin';
import { getWordStatus } from "utils/getWordStatus";
import { findIntelligibilityIssues } from "utils/intelligibilityIssues";

import { Table } from 'components/Table';
Expand Down Expand Up @@ -98,6 +99,7 @@ export const TranslationsModal =
}, []);

const hasMarks = new Set(Object.values(marks).filter(Boolean)).size > 0;
const wordStatus = getWordStatus(item)
const extraLegend = hasMarks && (<>
<br/>
⚠️ – {t('translationsLegendIntelligibilityWarning')}.<br/>
Expand All @@ -119,6 +121,11 @@ export const TranslationsModal =
</button>
</div>
<div className="modal-dialog__body">
{wordStatus && (
<div>
{wordStatus.icon}&nbsp;{t(wordStatus.text)}
</div>
)}
<Table data={tableData}/>
</div>
<footer className="modal-dialog__footer">
Expand Down
2 changes: 2 additions & 0 deletions src/components/ResultsCard/ResultCard.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const enIsvItemMock = {
"caseInfo": "",
"details": "m.anim.",
"ipa": "kɔt",
"id": "1093",
"checked": true,
"raw": ["1093", "kot", "", "m.anim.", "cat, tom-cat", "кот", "кот", "кіт", "kot, kocur", "kocour, kot", "kocúr, kot", "!Mačka", "mačak, mačor", "мачак, мачор", "мачор", "котарак", "!"],
"from": "en",
Expand All @@ -40,6 +41,7 @@ const isvEnItemMock = {
"caseInfo": "",
"details": "m.anim.",
"ipa": "kɔt",
"id": "1093",
"checked": true,
"raw": ["1093", "kot", "", "m.anim.", "cat, tom-cat", "кот", "кот", "кіт", "kot, kocur", "kocour, kot", "kocúr, kot", "!Mačka", "mačak, mačor", "мачак, мачор", "мачор", "котарак", "!"],
"from": "isv",
Expand Down
36 changes: 22 additions & 14 deletions src/components/ResultsCard/ResultsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Dictionary, ITranslateResult } from 'services/dictionary';
import { useAlphabets } from 'hooks/useAlphabets';
import { useCaseQuestions } from 'hooks/useCaseQuestions';
import { useLang } from 'hooks/useLang';
import { estimateIntelligibility, hasIntelligibilityIssues } from "utils/intelligibilityIssues";
import { getWordStatus } from "utils/getWordStatus";
import { toQueryString } from 'utils/toQueryString';
import { getPartOfSpeech } from 'utils/wordDetails';
import { wordHasForms } from 'utils/wordHasForms';
Expand Down Expand Up @@ -81,27 +81,42 @@ function renderOriginal(item, alphabets, caseQuestions) {
return (
<span className="word" key={i}>
<Clipboard str={str} />
{caseInfo && <> <span className="caseInfo">({caseInfo})</span></>}
{caseInfo && <span className="caseInfo">({caseInfo})</span>}
</span>
);
})}
{!caseQuestions && item.caseInfo &&
<> <span className="caseInfo">(+{t(`case${item.caseInfo.slice(1)}`)})</span></>
<span className="caseInfo">(+{t(`case${item.caseInfo.slice(1)}`)})</span>
}
{item.ipa && <> <span className="ipa">[{item.ipa}]</span></>}
{item.ipa && <span className="ipa">[{item.ipa}]</span>}
</>
);
}

const WordStatus = ({ item, onClick }: { item: ITranslateResult, onClick: () => void }) => {
const wordStatus = getWordStatus(item)

if (wordStatus) {
return (
<button
key="wordStatus"
onClick={onClick}
className="results-card__status"
title={t(wordStatus.text)}
>
{wordStatus.icon}
</button>
);
}
}

export const ResultsCard =
({ item, short, index }: IResultsCardProps) => {
const alphabets = useAlphabets();
const caseQuestions = useCaseQuestions();
const wordId = Dictionary.getField(item.raw, 'id')?.toString();
const pos = getPartOfSpeech(item.details);
const dispatch = useDispatch();
const intelligibility = Dictionary.getField(item.raw, 'intelligibility');
const intelligibilityVector = estimateIntelligibility(intelligibility);
const lang = useLang();

const showTranslations = () => {
Expand Down Expand Up @@ -167,14 +182,7 @@ export const ResultsCard =
<Clipboard str={item.translate} />
) : renderOriginal(item, alphabets, caseQuestions)}
{'\u00A0'}
{ hasIntelligibilityIssues(intelligibilityVector)
? <button
key="intelligibilityIssues"
onClick={showTranslations}
className={classNames({ 'results-card__status': true })}
title={t('intelligibilityIssues')}>⚠️</button>
: undefined
}
<WordStatus item={item} onClick={showTranslations}/>
{item.to === 'isv' && short && (
<>
&nbsp;
Expand Down
3 changes: 1 addition & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ declare global {

setInitialPage();

if ('serviceWorker' in navigator) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
navigator.serviceWorker.register(`sw.js`, { scope: '.' });
}


const root = createRoot(document.getElementById('app'));

root.render(
Expand Down
12 changes: 11 additions & 1 deletion src/services/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ export interface ITranslateResult {
to: string;
checked: boolean;
raw: string[];
id: string;
new?: boolean;
intelligibility?: string;
remove?: boolean;
}

class DictionaryClass {
Expand Down Expand Up @@ -507,13 +511,15 @@ class DictionaryClass {
): ITranslateResult[] {
return results.map((item) => {
const isv = this.getField(item, 'isv');
const id = this.getField(item, 'id');
const addArray = this.getField(item, 'addition').match(/\(.+?\)/) || [];
const add = addArray.find((elem) => !elem.startsWith('(+')) || '';
let caseInfo = convertCases(addArray.find((elem) => elem.startsWith('(+'))?.slice(1,-1) || '');
if(caseInfo && caseQuestions) {
caseInfo = getCaseTips(caseInfo.slice(1),'nounShort');
}
const translate = this.getField(item, (from === 'isv' ? to : from));
const remove = isv.startsWith('!');
const formattedItem: ITranslateResult = {
translate: removeExclamationMark(translate),
original: getLatin(isv, flavorisationType),
Expand All @@ -523,9 +529,13 @@ class DictionaryClass {
ipa: latinToIpa(getLatin(removeBrackets(isv, '[', ']'), flavorisationType)),
checked: translate[0] !== '!',
raw: item,
new: id.startsWith('-'),
intelligibility: this.getField(item, 'intelligibility'),
remove,
from,
to,
isv,
isv: remove ? isv.substring(1) : isv,
id,
};
if (alphabets?.cyrillic) {
formattedItem.originalCyr = getCyrillic(isv, flavorisationType);
Expand Down
32 changes: 31 additions & 1 deletion src/translations/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -3243,7 +3243,7 @@
},
"intelligibilityIssues": {
"en": "The word is not universally intelligible across Slavic languages",
"isv": "Slovo ne je universalno razumljivo vo vsih slovjanskyh jezykah",
"isv": "Slovo ne je universalno razumlivo vo vsih slovjanskyh jezykah",
"ru": "Слово не является универсально понятным во всех славянских языках",
"uk": "Слово не є універсально зрозумілим у всіх слов'янських мовах",
"be": "Слова не з’яўляецца ўніверсальна зразумелым ва ўсіх славянскіх мовах",
Expand All @@ -3255,5 +3255,35 @@
"sr": "Реч није универзално разумљива у свим словенским језицима",
"mk": "Зборот не е универзално разбирлив во сите словенски јазици",
"bg": "Думата не е универсално разбираема във всички слаавянски езици"
},
"suggestedNewWord": {
"en": "The word was recently added and has not yet been approved",
"isv": "Slovo bylo dodano nedavno i ješče ne jest odobrjeno",
"ru": "Слово добавлено недавно и ещё не утверждено",
"uk": "Слово було нещодавно додано та ще не затверджено",
"be": "Слова было нядаўна дададзена і яшчэ не зацверджана",
"pl": "Słowo zostało dodane niedawno i jeszcze nie zostało zatwierdzone",
"cs": "Slovo bylo nedávno přidáno a ještě nebylo schváleno",
"sk": "Slovo bolo nedávno pridané a ešte nebolo schválené",
"sl": "Beseda je bila nedavno dodana in še ni bila odobrena",
"hr": "Riječ je nedavno dodana i još nije odobrena",
"sr": "Реч је недавно додата и још увек није одобрена",
"mk": "Зборот неодамна беше додаден и сè уште не е одобрен",
"bg": "Думата беше добавена наскоро и все още не е одобрена"
},
"suggestedForRemoval": {
"en": "Suggested for removal from the dictionary",
"isv": "Prědloženo do udaljeńja iz slovnika",
"ru": "Предложено для удаления из словаря",
"uk": "Пропонується до видалення зі словника",
"be": "Прапануецца выдаліць са слоўніка",
"pl": "Sugerowane usunięcie ze słownika",
"cs": "Doporučeno k odstranění ze slovníku",
"sk": "Navrhnuté na odstránenie zo slovníka",
"sl": "Predlagano za odstranitev iz slovarja",
"hr": "Predloženo za uklanjanje iz rječnika",
"sr": "Предложено за уклањање из речника",
"mk": "Предложено за отстранување од речникот",
"bg": "Предлага се за премахване от речника"
}
}
33 changes: 33 additions & 0 deletions src/utils/getWordStatus/getWordStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ITranslateResult } from "services/dictionary";

import { estimateIntelligibility, hasIntelligibilityIssues } from "utils/intelligibilityIssues";

interface IWordStatus {
icon: string;
text: string;
}

export const getWordStatus = (item: ITranslateResult): IWordStatus | undefined => {
const intelligibilityVector = estimateIntelligibility(item.intelligibility);

if (hasIntelligibilityIssues(intelligibilityVector)) {
return {
icon: '⚠️',
text: 'intelligibilityIssues',
}
}

if (item.new) {
return {
icon: '🌱',
text: 'suggestedNewWord',
}
}

if (item.remove) {
return {
icon: '⛔️',
text: 'suggestedForRemoval',
}
}
}
1 change: 1 addition & 0 deletions src/utils/getWordStatus/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { getWordStatus } from './getWordStatus';

0 comments on commit 2a3e7a7

Please sign in to comment.