Skip to content

Commit

Permalink
refine the user interface for ingredients (#884)
Browse files Browse the repository at this point in the history
update interface
  • Loading branch information
alexfauquette authored Feb 18, 2024
1 parent c8cc4ed commit c36df59
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 19 deletions.
2 changes: 1 addition & 1 deletion crowdin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ files:
zh-TW: zh_TW
sr-CS: sr_CS
sr: sr_RS
ku : kmr_TR
ku: kmr_TR
kmr: kmr
9 changes: 8 additions & 1 deletion src/i18n/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,14 @@
"countryLabel": "Country"
},
"ingredients": {
"description": "This game allows you to validate the pre-selection of images of ingredients lists in various languages for a product, and validate the extracted ingredients."
"description": "This game allows you to validate the pre-selection of images of ingredients lists in various languages for a product, and validate the extracted ingredients.",
"current_text": "text from off",
"confidence_score": "language confidence",
"revert": "Revert",
"parsing": "Get server understanding",
"send": "Validate & send",
"skip": "Skip this product",
"getRobotoffPrediciton": "Get predictions from Robotoff"
},
"footer": {
"appStore": {
Expand Down
9 changes: 8 additions & 1 deletion src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,14 @@
"countryLabel": "Country"
},
"ingredients": {
"description": "This game allows you to validate the pre-selection of images of ingredients lists in various languages for a product, and validate the extracted ingredients."
"description": "This game allows you to validate the pre-selection of images of ingredients lists in various languages for a product, and validate the extracted ingredients.",
"current_text": "text from off",
"confidence_score": "language confidence",
"revert": "Revert",
"parsing": "Get server understanding",
"send": "Validate & send",
"skip": "Skip this product",
"getRobotoffPrediciton": "Get predictions from Robotoff"
},
"footer": {
"appStore": {
Expand Down
6 changes: 4 additions & 2 deletions src/pages/ingredients/ImageAnnotation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import useRobotoffPrediction, { DataType } from "./useRobotoffPrediction";
import { IngredientAnotation } from "./IngeredientDisplay";
import { useTranslation } from "react-i18next";

type ImageAnnotationProps = {
fetchDataUrl: string;
Expand Down Expand Up @@ -67,7 +68,7 @@ function Annotation({
<React.Fragment>
<IngredientAnotation
lang={imageLang}
score={'user'}
score={null}
code={code}
setEditedState={setOffEditedState}
text={offEditedState[imageLang].text}
Expand Down Expand Up @@ -127,6 +128,7 @@ export default function ImageAnnotation({
offText,
}: ImageAnnotationProps) {
const [data, getData, isLoading, error] = useRobotoffPrediction(fetchDataUrl);
const { t } = useTranslation();

return (
<Box sx={{ px: 1, width: "50%" }}>
Expand All @@ -144,7 +146,7 @@ export default function ImageAnnotation({
onClick={getData}
variant="outlined"
>
Get prediction
{t("ingredients.getRobotoffPrediciton")}
</Button>
</Box>
);
Expand Down
52 changes: 39 additions & 13 deletions src/pages/ingredients/IngeredientDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import * as React from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import LoadingButton from "@mui/lab/LoadingButton";

import { useTranslation } from "react-i18next";

import off from "../../off";

type BooleanEstimation = "no" | "yes" | "maybe";
Expand All @@ -27,6 +30,14 @@ function getColor(ingredient: ParsedIngredientsType) {
if (ingredient.ingredients !== undefined) return "blue";
return "orange";
}

function getTitle(ingredient: ParsedIngredientsType) {
if (ingredient.ciqual_proxy_food_code !== undefined)
return "This ingredient has CIQUAL id";
if (ingredient.vegetarian !== undefined) return "recognised as a vegetarian";
if (ingredient.ingredients !== undefined) return "contains sub ingredients";
return `unknown ingredient: ${ingredient.text}"`;
}
function ColorText({
text,
ingredients,
Expand All @@ -38,7 +49,7 @@ function ColorText({
// Without parsing, we just split with coma
return text.split(",").map((txt, i) => (
<React.Fragment key={i}>
<span style={{ color: i % 2 === 0 ? "blue" : "red" }}>{txt}</span>
<span style={{ color: i % 2 === 0 ? "gray" : "black" }}>{txt}</span>
{i === text.split(",").length - 1 ? "" : ","}
</React.Fragment>
));
Expand All @@ -63,16 +74,19 @@ function ColorText({
}
const endIndex = startIndex + ingredient.text.length;

console.log(text.slice(lastIndex, endIndex));
console.log("");
const prefix = text.slice(lastIndex, startIndex);
const ingredientName = text.slice(startIndex, endIndex);
lastIndex = endIndex;

return (
<React.Fragment key={i}>
<span>{prefix}</span>
<span style={{ color: getColor(ingredient) }}>{ingredientName}</span>

<Tooltip title={getTitle(ingredient)} enterDelay={500}>
<span style={{ color: getColor(ingredient) }}>
{ingredientName}
</span>
</Tooltip>
</React.Fragment>
);
}),
Expand Down Expand Up @@ -100,8 +114,7 @@ export function useIngredientParsing() {

export function IngeredientDisplay(props) {
const { text, onChange, parsings } = props;
console.log({ text });
console.log({ parsings });

return (
<div
id="demoSource-:rd:"
Expand All @@ -120,6 +133,8 @@ export function IngeredientDisplay(props) {
fontSmooth: "subpixel-antialiased",
float: "left",
minWidth: "100%",
minHeight: "3rem",
border: "solid black 1px",
}}
>
<pre
Expand All @@ -144,7 +159,7 @@ export function IngeredientDisplay(props) {
wordBreak: "keep-all",
overflowWrap: "break-word",
position: "relative",
pointerEvents: "none",
// pointerEvents: "none",
padding: "16px",
whiteSpace: "pre-wrap",
}}
Expand Down Expand Up @@ -193,18 +208,29 @@ export function IngeredientDisplay(props) {
WebkitTextFillColor: "transparent",
}}
value={text}
></textarea>
/>
</div>
);
}

export function IngredientAnotation(props) {
const { t } = useTranslation();
const { lang, score, code, setEditedState, text, detectedText } = props;
const { isLoading, fetchIngredients, parsings } = useIngredientParsing();

return (
<Stack direction="column">
<Typography>{`${lang} (${(score * 100).toFixed(1)}%)`}</Typography>
<Stack direction="column" sx={{ mt: 2 }}>
<Typography>
{lang}
{score === null ? (
<span> ({t("ingredients.current_text")})</span>
) : (
<span>
{" "}
({t("ingredients.confidence_score")}: {(score * 100).toFixed(1)}%)
</span>
)}
</Typography>
<Stack direction="row">
<IngeredientDisplay
parsings={parsings}
Expand Down Expand Up @@ -235,14 +261,14 @@ export function IngredientAnotation(props) {
variant="contained"
fullWidth
>
Revert
{t("ingredients.revert")}
</Button>
<LoadingButton
onClick={() => fetchIngredients(text, lang)}
fullWidth
loading={isLoading}
>
get parsing
{t("ingredients.parsing")}
</LoadingButton>
<Button
component="a"
Expand All @@ -253,7 +279,7 @@ export function IngredientAnotation(props) {
color="success"
fullWidth
>
Send
{t("ingredients.send")}
</Button>
</Stack>
</Stack>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/ingredients/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ImageAnnotation from "./ImageAnnotation";

function ProductInterface(props) {
const { product, next } = props;
const { t } = useTranslation();

const { selectedImages, product_name, code } = product;
const [imageTab, setImageTab] = React.useState(selectedImages[0].countryCode);
Expand Down Expand Up @@ -80,7 +81,7 @@ function ProductInterface(props) {
)}
</Stack>
<Button onClick={next} fullWidth variant="outlined">
Skip this product
{t("ingredients.skip")}
</Button>
</div>
);
Expand Down

0 comments on commit c36df59

Please sign in to comment.