Add language selection on card creation, move wiktionary functionality to lib folder

This commit is contained in:
Thiago Chaves 2022-08-10 18:38:20 +03:00
parent 1f5f87999b
commit 1ea6ff51a8
4 changed files with 52 additions and 13 deletions

View File

@ -0,0 +1,2 @@
export * from "./localStorage";
export * from "./parseWiktionaryData";

View File

@ -0,0 +1,9 @@
export const WiktionaryStorageKey = "wiktionary-language";
export function getWiktionaryWordLanguage() {
return localStorage.getItem(WiktionaryStorageKey) || "Finnish";
}
export function setWiktionaryWordLanguage(value: string) {
localStorage.setItem(WiktionaryStorageKey, value);
}

View File

@ -1,17 +1,24 @@
import { Expression } from "./types";
import { Expression } from "../../model/types";
export function parseWiktionaryData(
prompt: string,
data: string
): Expression | null {
// Prevent next.js SSR from crashing here
if (typeof window === "undefined") return null;
// Currently only supports en.wiktionary.org (Wiktionary in English language)
// ^^
interface ParseWiktionaryDataArguments {
prompt: string;
language: string;
data: string;
}
export function parseWiktionaryData({
prompt,
language,
data,
}: ParseWiktionaryDataArguments): Expression | null {
const parser = new DOMParser();
const document = parser.parseFromString(data, "text/html");
// TODO settings-based language selection
const header = document.getElementById("Finnish")?.parentElement;
const header = document.getElementById(language)?.parentElement;
if (!header) return null;
// Grab window of wanted elements and filter out unwanted elements within the window

View File

@ -2,11 +2,16 @@ import { useState } from "react";
import URL from "url";
import { ExpressionCard } from "../../components";
import { ExpressionDescription } from "../../components/ExpressionDescription";
import {
getWiktionaryWordLanguage,
parseWiktionaryData,
setWiktionaryWordLanguage,
} from "../../lib/wiktionary";
import { addExpressionWithRelationships, Expression } from "../../model";
import { parseWiktionaryData } from "../../model/parseWiktionaryData";
export function AddExpressionView() {
const [prompt, setPrompt] = useState("");
const [language, setLanguage] = useState(getWiktionaryWordLanguage());
const [expression, setExpression] = useState<Expression | null>(null);
const [submitStatus, setSubmitStatus] =
useState<string | undefined>(undefined);
@ -28,6 +33,20 @@ export function AddExpressionView() {
/>
) : (
<div className="content-query">
<label htmlFor="word-language">Language of the word: </label>
<select
value={language}
onChange={(event) => {
setWiktionaryWordLanguage(event.target.value);
setLanguage(event.target.value);
}}
id="word-language"
name="word-language"
>
<option value="Finnish">Finnish</option>
<option value="Portuguese">Portuguese</option>
<option value="Spanish">Spanish</option>
</select>
<label htmlFor="query">Word: </label>
<input
autoComplete="off"
@ -69,15 +88,17 @@ export function AddExpressionView() {
});
const result = await fetch(url);
const data = await result.json();
const expressionData = parseWiktionaryData(
const expressionData = parseWiktionaryData({
prompt,
data.parse?.text?.["*"] || ""
);
language,
data: data.parse?.text?.["*"] || "",
});
if (!expressionData)
throw new Error(
`Unable to find expression "${prompt}" on Wiktionary in the given language`
`Unable to find ${language}-language word "${prompt}" on Wiktionary`
);
setExpression(expressionData);
setError(undefined);
} catch (error) {
setError(error);
}