Skip to content

Commit

Permalink
Add word translation modal
Browse files Browse the repository at this point in the history
  • Loading branch information
Nitrino committed Aug 11, 2023
1 parent 4bf8ee2 commit 9c2ade8
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 70 deletions.
3 changes: 2 additions & 1 deletion src/assets/style/content/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
transform: translate3d(-50%, -100%, 0);
background-color: #1e1e1e;
border-radius: 0.4em;
font-size: 16px;
font-size: 18px;
width: 100%;
font-style: normal;
white-space: normal;
Expand All @@ -67,6 +67,7 @@
padding: 16px 24px;
box-sizing: border-box;
white-space: pre-wrap;
text-wrap: balance;

&:after {
content: "";
Expand Down
37 changes: 26 additions & 11 deletions src/assets/style/content/word-translation.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.es-word-translation {
width: max-content;
max-width: 360px;
min-width: 200px;
text-align: left;
position: absolute;
top: 0px;
Expand Down Expand Up @@ -67,30 +68,44 @@
.es-translation-variants {
margin: 12px 0;
font-size: 14px;

table {
border-collapse: separate;
border-spacing: 0 4px;
}
display: grid;
grid-template-columns: fit-content(120px) auto 1fr;
column-gap: 16px;
row-gap: 4px;
align-items: center;
}

.es-translation-variant {
svg {
vertical-align: middle;
}
.es-translation-phrasal-verbs-variants {
display: flex;
flex-direction: column;
gap: 4px;
font-size: 14px;
margin: 12px 0;
}

.es-translation-variant-word {
max-width: 120px;
hyphens: auto;
display: flex;
align-items: center;

.es-settings-button {
flex: 0 0 14px;

svg {
vertical-align: middle;
width: 100%;
padding-bottom: 2px;
}
}
}

.es-translation-variant-part-of-speach {
text-align: left;
color: #737373;
padding: 0 16px;
}

.es-translation-variant-synonyms {
width: fit-content;
color: #bbbbbb;
flex: 1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/learning-service/anki.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ILearningService from "./learningService";
import ILearningService, { TAditionalData } from "./learningService";

const ANKI_API_VERSION = 6;
const ANKI_DESK = "Easysubs";
Expand All @@ -11,7 +11,7 @@ export class Anki implements ILearningService {
this.color = "#0d6efd";
}

public async addWord(word: string, translation: string, aditionalData: Record<string, string>): Promise<string> {
public async addWord(word: string, translation: string, aditionalData: TAditionalData): Promise<string> {
const createDeskResult = await chrome.runtime.sendMessage({
type: "post",
url: ANKI_URL,
Expand Down
6 changes: 5 additions & 1 deletion src/learning-service/learningService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export type TAditionalData = {
context?: string;
partOfSpeech?: string;
};
interface ILearningService {
color: string;
addWord: (word: string, translation: string, aditionalData: Record<string, string>) => Promise<string>;
addWord: (word: string, translation: string, aditionalData: TAditionalData) => Promise<string>;
}

export default ILearningService;
4 changes: 2 additions & 2 deletions src/learning-service/linguaLeo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ILearningService from "./learningService";
import ILearningService, { TAditionalData } from "./learningService";

export class LinguaLeo implements ILearningService {
public color: string;
Expand All @@ -7,7 +7,7 @@ export class LinguaLeo implements ILearningService {
this.color = "#FFC900";
}

public async addWord(word: string, translation: string, aditionalData: Record<string, string>): Promise<string> {
public async addWord(word: string, translation: string, aditionalData: TAditionalData): Promise<string> {
const url = new URL("https://api.lingualeo.com/addword");
const data = {
word: word,
Expand Down
4 changes: 2 additions & 2 deletions src/learning-service/puzzleEnglish.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ILearningService from "./learningService";
import ILearningService, { TAditionalData } from "./learningService";

export class PuzzleEnglish implements ILearningService {
public color: string;
Expand All @@ -7,7 +7,7 @@ export class PuzzleEnglish implements ILearningService {
this.color = "#88BA28";
}

public async addWord(word: string, translation: string, aditionalData: Record<string, string>): Promise<string> {
public async addWord(word: string, translation: string, aditionalData: TAditionalData): Promise<string> {
const url = "https://puzzle-english.com/api2/userDictionary/addWord";
const data = {
post_id: 0,
Expand Down
62 changes: 62 additions & 0 deletions src/pages/content/components/Subs/PhrasalVerbTranslation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { FC, useEffect, useState } from "react";
import { useUnit } from "effector-react";

import { TPhrasalVerb } from "@src/models/types";
import { cleanWordTranslation, requestWordTranslation } from "@src/models/translations";
import { $learningService } from "@src/models/settings";
import { $subsLanguage } from "@src/models/subs";
import ILearningService from "@src/learning-service/learningService";
import { getLearningService } from "@src/utils/getLearningService";
import toast from "react-hot-toast";
import { PlusIcon } from "./assets/PlusIcon";

export const PhrasalVerbTranslation: FC<{ phrasalVerb: TPhrasalVerb }> = ({ phrasalVerb }) => {
const [learningService] = useUnit([$learningService, requestWordTranslation, cleanWordTranslation, $subsLanguage]);

const [service, setService] = useState<ILearningService>(null);

useEffect(() => {
setService(getLearningService(learningService));
}, [learningService]);

const handleAddWord = (word: string, translation: string) => {
if (service) {
service
.addWord(word.toLowerCase(), translation, { partOfSpeech: "phrase" })
.then((value) => {
toast.success(value);
})
.catch((error) => {
toast.error(error);
});
}
};

return (
<div className="es-word-translation">
<div className="es-word-main">{phrasalVerb.text}</div>
<hr className="es-word-original-hr" />
<div className="es-word-original-info">
<div className="es-word-original">phrasal verb</div>
</div>
<div className="es-translation-phrasal-verbs-variants">
{phrasalVerb.translations.map((translation) => (
<div className="es-translation-variant-word">
{service && (
<button
className="es-settings-button"
onClick={(e) => {
e.stopPropagation();
handleAddWord(phrasalVerb.text, translation);
}}
>
<PlusIcon fill={service.color} />
</button>
)}
{translation}
</div>
))}
</div>
</div>
);
};
65 changes: 25 additions & 40 deletions src/pages/content/components/Subs/SubItemTranslation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import { useUnit } from "effector-react";

import { $learningService } from "@src/models/settings";
import { $currentWordTranslation, cleanWordTranslation, requestWordTranslation } from "@src/models/translations";
import { Anki } from "@src/learning-service/anki";
import { LinguaLeo } from "@src/learning-service/linguaLeo";
import { PuzzleEnglish } from "@src/learning-service/puzzleEnglish";
import toast from "react-hot-toast";
import { SoundIcon } from "./assets/SoundIcon";
import { PlusIcon } from "./assets/PlusIcon";
Expand All @@ -18,6 +15,7 @@ import youglishIcon from "@assets/img/icons/youglish.png";
import ILearningService from "@src/learning-service/learningService";
import { TWordTranslationItem } from "@src/models/types";
import { $subsLanguage } from "@src/models/subs";
import { getLearningService } from "@src/utils/getLearningService";

export const SubItemTranslation: FC<{ text: string }> = ({ text }) => {
const [
Expand All @@ -31,15 +29,7 @@ export const SubItemTranslation: FC<{ text: string }> = ({ text }) => {
const [service, setService] = useState<ILearningService>(null);

useEffect(() => {
if (learningService === "anki") {
setService(new Anki());
}
if (learningService === "lingualeo") {
setService(new LinguaLeo());
}
if (learningService === "puzzle-english") {
setService(new PuzzleEnglish());
}
setService(getLearningService(learningService));
}, [learningService]);

useEffect(() => {
Expand All @@ -53,10 +43,10 @@ export const SubItemTranslation: FC<{ text: string }> = ({ text }) => {
return null;
}

const handleAddWord = (wors: string, translation: TWordTranslationItem) => {
const handleAddWord = (word: string, translation: TWordTranslationItem) => {
if (service) {
service
.addWord(wors.toLowerCase(), translation.word, {})
.addWord(word.toLowerCase(), translation.word, { partOfSpeech: translation.partOfSpeech })
.then((value) => {
toast.success(value);
})
Expand All @@ -76,37 +66,32 @@ export const SubItemTranslation: FC<{ text: string }> = ({ text }) => {
<hr className="es-word-original-hr" />
<div className="es-word-original-info">
<div className="es-word-original">{text.toLowerCase()}</div>
{currentWordTranslation.transcription && <div>/{currentWordTranslation.transcription}/</div>}
<div className="es-word-original-sound-icon" onClick={handlePlaySound}>
<SoundIcon />
</div>
</div>
<div className="es-translation-variants">
<table>
<tbody>
{currentWordTranslation.translations.length > 0 &&
currentWordTranslation.translations.map((translation) => (
<tr className="es-translation-variant">
{service && (
<td>
<button
className="es-settings-button"
onClick={(e) => {
e.stopPropagation();
handleAddWord(currentWordTranslation.source, translation);
}}
>
<PlusIcon fill={service.color} />
</button>
</td>
)}
<td className="es-translation-variant-word">{translation.word}</td>
<td className="es-translation-variant-part-of-speach">{translation.partOfSpeech}</td>
<td className="es-translation-variant-synonyms">{joinTranslations(translation.synonyms)}</td>
</tr>
))}
</tbody>
</table>
{currentWordTranslation.translations.length > 0 &&
currentWordTranslation.translations.map((translation) => (
<>
<div className="es-translation-variant-word">
{service && (
<button
className="es-settings-button"
onClick={(e) => {
e.stopPropagation();
handleAddWord(currentWordTranslation.source, translation);
}}
>
<PlusIcon fill={service.color} />
</button>
)}
<div>{translation.word}</div>
</div>
<div className="es-translation-variant-part-of-speach">{translation.partOfSpeech}</div>
<div className="es-translation-variant-synonyms">{joinTranslations(translation.synonyms)}</div>
</>
))}
</div>
{subsLanguage === "en" && (
<>
Expand Down
11 changes: 1 addition & 10 deletions src/pages/content/components/Subs/Subs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { addKeyboardEventsListeners, removeKeyboardEventsListeners } from "@src/
import { findPhrasalVerbs } from "@src/utils/findPhrasalVerbs";
import { joinTranslations } from "@src/utils/joinTranslations";
import { SubItemTranslation } from "./SubItemTranslation";
import { PhrasalVerbTranslation } from "./PhrasalVerbTranslation";

type TSubsProps = {};

Expand Down Expand Up @@ -159,16 +160,6 @@ const SubItem: FC<TSubItemProps> = ({ subItem, phrasalVerbs, index }) => {
);
};

const PhrasalVerbTranslation: FC<{ phrasalVerb: TPhrasalVerb }> = ({ phrasalVerb }) => {
return (
<div className="es-word-translation">
<div className="es-word-translation-original">{phrasalVerb.text}</div>
<hr />
<div className="es-word-word-translations">{joinTranslations(phrasalVerb.translations)}</div>
</div>
);
};

const SubFullTranslation: FC<{ text: string }> = ({ text }) => {
const [currentSubTranslation, handleRequestSubTranslation, handleCleanSubTranslation] = useUnit([
$currentSubTranslation,
Expand Down
1 change: 0 additions & 1 deletion src/utils/findPhrasalVerbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const findPhrasalVerbs = (text: string): TPhrasalVerb[] => {

Object.entries(PHRASAL_VERBS).forEach(([key, item]) => {
const phrasalVerbList: string[] = [key, ...(item["derivatives"] ?? [])];

for (const phrasalVerb of phrasalVerbList) {
const phrasalVerbWords = phrasalVerb.match(/[^ ]+/g);
if (words.includes(phrasalVerbWords[0])) {
Expand Down
16 changes: 16 additions & 0 deletions src/utils/getLearningService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Anki } from "@src/learning-service/anki";
import { LinguaLeo } from "@src/learning-service/linguaLeo";
import { PuzzleEnglish } from "@src/learning-service/puzzleEnglish";
import { TLearningService } from "@src/models/types";

export const getLearningService = (learningService: TLearningService) => {
if (learningService === "anki") {
return new Anki();
}
if (learningService === "lingualeo") {
return new LinguaLeo();
}
if (learningService === "puzzle-english") {
return new PuzzleEnglish();
}
};

0 comments on commit 9c2ade8

Please sign in to comment.