diff --git a/renderer/components/Meaning/MeaningBox.tsx b/renderer/components/Meaning/MeaningBox.tsx
index 43b6e4f..0b85642 100644
--- a/renderer/components/Meaning/MeaningBox.tsx
+++ b/renderer/components/Meaning/MeaningBox.tsx
@@ -36,7 +36,9 @@ const OutlinedStar = ({color, size, outlineColor = 'black', outlineWidth = 1}) =
const initialContentState = {
id: "",
sense: [],
- single: []
+ single: [],
+ content: '',
+ simplified: ''
};
const initialCharacterContentState = {literal: null};
@@ -118,17 +120,26 @@ const MeaningBox = ({
useEffect(() => {
const fetchRomajiedData = async () => {
- const data = await Promise.all(
- meaningContent.single.map(async (val) => ({
- key: val.key,
- romajied: await tokenizeMiteiru(val.text)
- }))
- );
- setRomajiedData(data);
+ console.log(meaningContent);
+ if (lang === videoConstants.japaneseLang) {
+ const data = await Promise.all(
+ meaningContent.single.map(async (val) => {
+ return ({
+ key: val.key,
+ romajied: await tokenizeMiteiru(val.text)
+ });
+ })
+ );
+ setRomajiedData(data);
+ } else if (lang === videoConstants.cantoneseLang || videoConstants.chineseLang) {
+ const usedData = (meaningContent.simplified.includes(meaning)) ? meaningContent.simplified : meaningContent.content;
+ const data = [{key: 0, romajied: (await tokenizeMiteiru(usedData))}];
+ setRomajiedData(data);
+ }
};
if (meaningContent.single.length) fetchRomajiedData();
- }, [meaningContent.single, tokenizeMiteiru]);
+ }, [lang, meaning, meaningContent, tokenizeMiteiru]);
const handleBGClick = useCallback(() => setMeaning(''), [setMeaning]);
@@ -234,7 +245,6 @@ const MeaningContent = ({meaningContent, lang, tags}) => {
const RomajiedContent = ({romajied, lang, setMeaning, subtitleStyling}) => {
const queryText = romajied.reduce((acc, next) => acc + next.origin, "");
-
return (
{
extraClass="unselectable meaning-kanji text-md"
subtitleStyling={subtitleStyling}/>
))}
- {(lang === videoConstants.chineseLang || lang === videoConstants.cantoneseLang) && romajied.map((val, idx) => (
-
- ))}
+ {(lang === videoConstants.chineseLang || lang === videoConstants.cantoneseLang) && romajied.map((val, idx) => {
+ return (
+
+
+ );
+ })}
diff --git a/renderer/components/VideoPlayer/VocabSidebar.tsx b/renderer/components/VideoPlayer/VocabSidebar.tsx
index 6626de2..f9f395a 100644
--- a/renderer/components/VideoPlayer/VocabSidebar.tsx
+++ b/renderer/components/VideoPlayer/VocabSidebar.tsx
@@ -3,10 +3,21 @@ import React, {useState, useEffect, useCallback} from 'react';
import {ipcRenderer} from 'electron';
import {getColorGradient, getRelativeTime} from '../../utils/utils';
import {ArrowRight} from "./Icons";
-import {AwesomeButton} from "react-awesome-button";
+import {HanziSentence, KanjiSentence} from "../Subtitle/Sentence";
+import {videoConstants} from "../../utils/constants";
+import {defaultLearningStyling, defaultMeaningBoxStyling} from "../../utils/CJKStyling";
+import SmoothCollapse from "react-smooth-collapse";
-const VocabSidebar = ({showVocabSidebar, setShowVocabSidebar, lang, setMeaning}) => {
+const VocabSidebar = ({
+ showVocabSidebar,
+ setShowVocabSidebar,
+ lang,
+ setMeaning,
+ tokenizeMiteiru
+ }) => {
const [sortedVocab, setSortedVocab] = useState([]);
+ const [hoveredWord, setHoveredWord] = useState(null);
+ const [tokenizedWord, setTokenizedWord] = useState(null);
const loadVocabulary = useCallback(async () => {
try {
@@ -26,22 +37,28 @@ const VocabSidebar = ({showVocabSidebar, setShowVocabSidebar, lang, setMeaning})
setMeaning(word);
}, [setMeaning]);
- const saveVocabHandler = useCallback(() => {
- ipcRenderer.invoke('loadLearningState', lang).then((val) => {
- ipcRenderer.invoke("saveFile", ["json"], JSON.stringify(val))
- })
- }, [lang]);
+ const handleMouseEnter = useCallback(async (word) => {
+ setHoveredWord(word);
+ const tokenized = await tokenizeMiteiru(word);
+ setTokenizedWord(tokenized);
+ }, [tokenizeMiteiru]);
- const loadVocabHandler = useCallback(() => {
- ipcRenderer.invoke("readFile", ["json"]).then((val) => {
- try {
- const parsed = JSON.parse(val);
- ipcRenderer.invoke("updateContentBatch", parsed, lang)
- } catch (e) {
- console.error(e)
- }
- })
- }, [lang]);
+ const handleMouseLeave = useCallback(() => {
+ setHoveredWord(null);
+ setTokenizedWord(null);
+ }, []);
+
+ const renderTokenizedWord = useCallback(() => {
+ if (!tokenizedWord) return null;
+
+ if (lang === videoConstants.japaneseLang) {
+ return (tokenizedWord);
+ } else if (lang === videoConstants.chineseLang || lang === videoConstants.cantoneseLang) {
+ return (tokenizedWord.map(t => t.pinyin || t.jyutping));
+ }
+
+ return null;
+ }, [tokenizedWord, lang]);
return (
-
-
- Save Vocabulary
-
-
- Load Vocabulary
-
-
{sortedVocab.map((word) => (
jumpToWord(word[0])}
+ onMouseEnter={() => handleMouseEnter(word[0])}
+ onMouseLeave={handleMouseLeave}
style={{backgroundColor: getColorGradient(word[1].updTime)}}
>
-
{word[0]}
-
{getRelativeTime(word[1].updTime)}
+
+ {word[0]}
+ {getRelativeTime(word[1].updTime)}
+
+ {hoveredWord === word[0] && renderTokenizedWord()}
))}
diff --git a/renderer/pages/video.tsx b/renderer/pages/video.tsx
index 9296f6f..6974622 100644
--- a/renderer/pages/video.tsx
+++ b/renderer/pages/video.tsx
@@ -225,6 +225,7 @@ function Video() {
setShowVocabSidebar={setShowVocabSidebar}
lang={lang}
setMeaning={setMeaning}
+ tokenizeMiteiru={tokenizeMiteiru}
/>
);