эмоджи выбирается и отправляется на бек
This commit is contained in:
parent
522d8f14a4
commit
2e8325bf00
@ -107,41 +107,46 @@ export const EmojiVariant = ({
|
|||||||
ownPlaceholder,
|
ownPlaceholder,
|
||||||
}: EmojiVariantProps) => {
|
}: EmojiVariantProps) => {
|
||||||
const { settings } = useQuizStore();
|
const { settings } = useQuizStore();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const { updateAnswer, deleteAnswer, updateOwnVariant, ownVariants } = useQuizViewStore();
|
||||||
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const customEmoji = ownVariants.find((v) => v.id === variant.id)?.variant.extendedText || "";
|
||||||
|
|
||||||
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
|
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const variantId = variant.id;
|
const variantId = variant.id;
|
||||||
|
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
const currentAnswer = typeof answer !== "string" ? answer || [] : [];
|
const currentAnswer = Array.isArray(answer) ? answer : [];
|
||||||
|
const newAnswer = currentAnswer.includes(variantId)
|
||||||
return updateAnswer(
|
? currentAnswer.filter((item) => item !== variantId)
|
||||||
questionId,
|
: [...currentAnswer, variantId];
|
||||||
currentAnswer.includes(variantId)
|
updateAnswer(questionId, newAnswer, variant.points || 0);
|
||||||
? currentAnswer?.filter((item) => item !== variantId)
|
} else {
|
||||||
: [...currentAnswer, variantId],
|
if (answer === variant.id) {
|
||||||
variant.points || 0
|
deleteAnswer(questionId);
|
||||||
);
|
} else {
|
||||||
}
|
updateAnswer(questionId, variant.id, variant.points || 0);
|
||||||
|
}
|
||||||
updateAnswer(questionId, variant.id, variant.points || 0);
|
|
||||||
|
|
||||||
if (answer === variant.id) {
|
|
||||||
deleteAnswer(questionId);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEmojiSelect = (emoji: string) => {
|
||||||
|
// We store custom emoji in ownVariants store, with a specific field to differentiate
|
||||||
|
const currentOwnAnswer = ownVariants.find((v) => v.id === variant.id)?.variant.answer || "";
|
||||||
|
updateOwnVariant(variant.id, currentOwnAnswer, emoji);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSelected = isMulti ? Array.isArray(answer) && answer.includes(variant.id) : answer === variant.id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl
|
<FormControl
|
||||||
key={index}
|
key={index}
|
||||||
sx={{
|
sx={{
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
border: `1px solid`,
|
border: `1px solid`,
|
||||||
borderColor: answer?.includes(variant.id) ? theme.palette.primary.main : "#9A9AAF",
|
borderColor: isSelected ? theme.palette.primary.main : "#9A9AAF",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
maxWidth: "317px",
|
maxWidth: "317px",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@ -154,7 +159,6 @@ export const EmojiVariant = ({
|
|||||||
: "transparent",
|
: "transparent",
|
||||||
"&:hover": { borderColor: theme.palette.primary.main },
|
"&:hover": { borderColor: theme.palette.primary.main },
|
||||||
}}
|
}}
|
||||||
// value={index}
|
|
||||||
onClick={onVariantClick}
|
onClick={onVariantClick}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@ -167,7 +171,10 @@ export const EmojiVariant = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{own ? (
|
{own ? (
|
||||||
<OwnEmojiPicker emoji={variant.extendedText} />
|
<OwnEmojiPicker
|
||||||
|
emoji={customEmoji || variant.extendedText}
|
||||||
|
onEmojiSelect={handleEmojiSelect}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -222,13 +229,14 @@ export const EmojiVariant = ({
|
|||||||
control={
|
control={
|
||||||
isMulti ? (
|
isMulti ? (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={!!answer?.includes(variant.id)}
|
checked={isSelected}
|
||||||
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
|
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
|
||||||
icon={<RadioIcon />}
|
icon={<RadioIcon />}
|
||||||
sx={{ position: "absolute", top: "-162px", right: "12px" }}
|
sx={{ position: "absolute", top: "-162px", right: "12px" }}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Radio
|
<Radio
|
||||||
|
checked={isSelected}
|
||||||
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
|
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
|
||||||
icon={<RadioIcon />}
|
icon={<RadioIcon />}
|
||||||
sx={{ position: "absolute", top: "-162px", right: "12px" }}
|
sx={{ position: "absolute", top: "-162px", right: "12px" }}
|
||||||
|
@ -13,10 +13,11 @@ type EmojiProps = {
|
|||||||
|
|
||||||
export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
|
|
||||||
|
const selectedVariantId = Array.isArray(answer) ? answer[0] : answer;
|
||||||
|
|
||||||
if (moment.isMoment(answer)) throw new Error("Answer is Moment in Variant question");
|
if (moment.isMoment(answer)) throw new Error("Answer is Moment in Variant question");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -30,14 +31,7 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={currentQuestion.id}
|
name={currentQuestion.id}
|
||||||
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
value={selectedVariantId}
|
||||||
onChange={({ target }) =>
|
|
||||||
updateAnswer(
|
|
||||||
currentQuestion.id,
|
|
||||||
currentQuestion.content.variants[Number(target.value)].answer,
|
|
||||||
currentQuestion.content.variants[Number(target.value)].points || 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
|
@ -30,7 +30,7 @@ interface QuizViewStore {
|
|||||||
interface QuizViewActions {
|
interface QuizViewActions {
|
||||||
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
|
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
|
||||||
deleteAnswer: (questionId: string) => void;
|
deleteAnswer: (questionId: string) => void;
|
||||||
updateOwnVariant: (id: string, answer: string) => void;
|
updateOwnVariant: (id: string, answer: string, extendedText?: string) => void;
|
||||||
deleteOwnVariant: (id: string) => void;
|
deleteOwnVariant: (id: string) => void;
|
||||||
setCurrentQuizStep: (step: QuizStep) => void;
|
setCurrentQuizStep: (step: QuizStep) => void;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ export const createQuizViewStore = () =>
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
updateOwnVariant(id, answer) {
|
updateOwnVariant(id, answer, extendedText) {
|
||||||
set(
|
set(
|
||||||
(state) => {
|
(state) => {
|
||||||
const index = state.ownVariants.findIndex((variant) => variant.id === id);
|
const index = state.ownVariants.findIndex((variant) => variant.id === id);
|
||||||
@ -101,13 +101,16 @@ export const createQuizViewStore = () =>
|
|||||||
variant: {
|
variant: {
|
||||||
id: id,
|
id: id,
|
||||||
answer,
|
answer,
|
||||||
extendedText: "",
|
extendedText: extendedText || "",
|
||||||
hints: "",
|
hints: "",
|
||||||
originalImageUrl: "",
|
originalImageUrl: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
state.ownVariants[index].variant.answer = answer;
|
state.ownVariants[index].variant.answer = answer;
|
||||||
|
if (extendedText) {
|
||||||
|
state.ownVariants[index].variant.extendedText = extendedText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
|
@ -50,25 +50,17 @@ export async function sendQuestionAnswer(
|
|||||||
}
|
}
|
||||||
case "emoji": {
|
case "emoji": {
|
||||||
if (question.content.multi) {
|
if (question.content.multi) {
|
||||||
const answer = questionAnswer.answer;
|
const answer = questionAnswer.answer as string[];
|
||||||
const ownVariant = Array.isArray(answer)
|
let answerString = ``;
|
||||||
? ownVariants[ownVariants.findIndex((variant) => answer.some((a: string) => a === variant.id))]?.variant || ""
|
|
||||||
: ownVariants[ownVariants.findIndex((variant) => variant.id === questionAnswer.answer)]?.variant || "";
|
|
||||||
|
|
||||||
if (moment.isMoment(answer)) throw new Error("Answer is Moment in Variant question");
|
|
||||||
|
|
||||||
//Оставляем только выбранные варианты
|
|
||||||
const selectedVariants = question.content.variants.filter((v) => answer.includes(v.id));
|
const selectedVariants = question.content.variants.filter((v) => answer.includes(v.id));
|
||||||
|
|
||||||
let answerString = ``;
|
selectedVariants.forEach((variant) => {
|
||||||
selectedVariants.forEach((e) => {
|
const ownVariantData = ownVariants.find((v) => v.id === variant.id)?.variant;
|
||||||
if (e.isOwn) {
|
const customEmoji = ownVariantData?.extendedText || "";
|
||||||
if (question.content.own && selectedVariants.some((v) => v.isOwn)) {
|
const emojiToSend = customEmoji || variant.extendedText;
|
||||||
answerString += `\`${e.extendedText} ${ownVariant?.answer ?? ""}\`,`;
|
const textToSend = variant.isOwn ? ownVariantData?.answer || "" : variant.answer;
|
||||||
}
|
answerString += `\`${emojiToSend} ${textToSend}\`,`;
|
||||||
} else {
|
|
||||||
answerString += `\`${e.extendedText} ${e.answer ?? ""}\`,`;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
answerString = answerString.slice(0, -1);
|
answerString = answerString.slice(0, -1);
|
||||||
@ -80,12 +72,27 @@ export async function sendQuestionAnswer(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const variant = question.content.variants.find((v) => v.id === questionAnswer.answer);
|
// Fallback for old string format for single choice
|
||||||
if (!variant) throw new Error(`Cannot find variant with id ${questionAnswer.answer} in question ${question.id}`);
|
const answer = questionAnswer.answer as string;
|
||||||
|
const variant = question.content.variants.find((v) => v.id === answer);
|
||||||
|
if (!variant) {
|
||||||
|
// This can happen if the answer is not set, so we don't throw an error, just send empty
|
||||||
|
return sendAnswer({
|
||||||
|
questionId: question.id,
|
||||||
|
body: "",
|
||||||
|
qid: quizId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownVariantData = ownVariants.find((v) => v.id === variant.id)?.variant;
|
||||||
|
const customEmoji = ownVariantData?.extendedText || "";
|
||||||
|
const emojiToSend = customEmoji || variant.extendedText;
|
||||||
|
const textToSend = variant.isOwn ? ownVariantData?.answer || "" : variant.answer;
|
||||||
|
const body = `${emojiToSend} ${textToSend}`.trim();
|
||||||
|
|
||||||
return sendAnswer({
|
return sendAnswer({
|
||||||
questionId: question.id,
|
questionId: question.id,
|
||||||
body: variant.extendedText + " " + variant.answer,
|
body: body,
|
||||||
qid: quizId,
|
qid: quizId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user