hide ai
This commit is contained in:
parent
4190ae767e
commit
1f2880f719
@ -71,7 +71,7 @@ export const publicationMakeRequest = ({ url, body }: PublicationMakeRequestPara
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
let page = 0;
|
||||||
export async function getData(quizId: string): Promise<{
|
export async function getData(quizId: string): Promise<{
|
||||||
data: GetQuizDataResponse | null;
|
data: GetQuizDataResponse | null;
|
||||||
isRecentlyCompleted: boolean;
|
isRecentlyCompleted: boolean;
|
||||||
@ -92,16 +92,18 @@ export async function getData(quizId: string): Promise<{
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
quiz_id: quizId,
|
quiz_id: quizId,
|
||||||
limit: 100,
|
limit: 1,
|
||||||
page: 0,
|
page,
|
||||||
need_config: true,
|
need_config: page === 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
console.log(data);
|
||||||
|
if (data.items.length) page++;
|
||||||
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
||||||
|
|
||||||
//Тут ещё проверка на антифрод без парса конфига. Нам не интересно время если не нужно запрещать проходить чаще чем в сутки
|
//Тут ещё проверка на антифрод без парса конфига. Нам не интересно время если не нужно запрещать проходить чаще чем в сутки
|
||||||
if (typeof sessions[quizId] === "number" && data.settings.cfg.includes('antifraud":true')) {
|
if (!page && typeof sessions[quizId] === "number" && data.settings.cfg.includes('antifraud":true')) {
|
||||||
// unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
|
// unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
|
||||||
if (Date.now() - sessions[quizId] < 86400000) {
|
if (Date.now() - sessions[quizId] < 86400000) {
|
||||||
return { data, isRecentlyCompleted: true };
|
return { data, isRecentlyCompleted: true };
|
||||||
@ -118,27 +120,84 @@ export async function getData(quizId: string): Promise<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getQuizData(quizId: string) {
|
export async function getQuizData(quizId: string, status?: string): Promise<QuizSettings> {
|
||||||
|
let maxRetries = 50;
|
||||||
if (!quizId) throw new Error("No quiz id");
|
if (!quizId) throw new Error("No quiz id");
|
||||||
|
|
||||||
const response = await getData(quizId);
|
let lastError: Error | null = null;
|
||||||
const quizDataResponse = response.data;
|
let responseData: any = null;
|
||||||
|
|
||||||
if (response.error) {
|
// Первый цикл - обработка result вопросов с увеличением page
|
||||||
throw response.error;
|
let resultRetryCount = 0;
|
||||||
}
|
while (resultRetryCount < maxRetries) {
|
||||||
if (!quizDataResponse) {
|
try {
|
||||||
throw new Error("Quiz not found");
|
const response = await getData(quizId);
|
||||||
|
console.log("ф-я аналитики", response);
|
||||||
|
|
||||||
|
if (response.error) throw response.error;
|
||||||
|
if (!response.data) throw new Error("Quiz not found");
|
||||||
|
|
||||||
|
const hasAiResult = response.data.items.some((item) => item.typ === "result" && status === "ai");
|
||||||
|
|
||||||
|
if (hasAiResult) {
|
||||||
|
page++; // Увеличиваем страницу
|
||||||
|
resultRetryCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если result вопросов нет, сохраняем данные для второго цикла
|
||||||
|
responseData = response;
|
||||||
|
break;
|
||||||
|
} catch (error) {
|
||||||
|
lastError = error as Error;
|
||||||
|
resultRetryCount++;
|
||||||
|
if (resultRetryCount >= maxRetries) break;
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000 * resultRetryCount));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const quizSettings = replaceSpacesToEmptyLines(parseQuizData(quizDataResponse));
|
if (!responseData) {
|
||||||
|
throw lastError || new Error("Failed to get quiz data after result retries");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Второй цикл - обработка пустого массива items (без изменения page)
|
||||||
|
let isEmpty = !responseData.data?.items.length;
|
||||||
|
let emptyRetryCount = 0;
|
||||||
|
while (isEmpty && emptyRetryCount < maxRetries) {
|
||||||
|
try {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
|
const response = await getData(quizId);
|
||||||
|
|
||||||
|
if (response.error) throw response.error;
|
||||||
|
if (!response.data) throw new Error("Quiz not found");
|
||||||
|
|
||||||
|
isEmpty = !response.data.items.length;
|
||||||
|
if (!isEmpty) {
|
||||||
|
responseData = response; // Обновляем данные
|
||||||
|
}
|
||||||
|
emptyRetryCount++;
|
||||||
|
} catch (error) {
|
||||||
|
lastError = error as Error;
|
||||||
|
emptyRetryCount++;
|
||||||
|
if (emptyRetryCount >= maxRetries) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
throw new Error("Items array is empty after maximum retries");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Финальная обработка успешного ответа
|
||||||
|
const quizSettings = replaceSpacesToEmptyLines(parseQuizData(responseData.data));
|
||||||
|
|
||||||
const res = JSON.parse(
|
const res = JSON.parse(
|
||||||
JSON.stringify({ data: quizSettings })
|
JSON.stringify({ data: quizSettings })
|
||||||
.replaceAll(/\\" \\"/g, '""')
|
.replaceAll(/\\" \\"/g, '""')
|
||||||
.replaceAll(/" "/g, '""')
|
.replaceAll(/" "/g, '""')
|
||||||
).data as QuizSettings;
|
).data as QuizSettings;
|
||||||
res.recentlyCompleted = response.isRecentlyCompleted;
|
|
||||||
|
res.recentlyCompleted = responseData.isRecentlyCompleted;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +77,12 @@ function QuizAnswererInner({
|
|||||||
if (error) return <ApologyPage error={error} />;
|
if (error) return <ApologyPage error={error} />;
|
||||||
// if (!data) return <LoadingSkeleton />;
|
// if (!data) return <LoadingSkeleton />;
|
||||||
quizSettings ??= data;
|
quizSettings ??= data;
|
||||||
if (!quizSettings) return <ApologyPage error={new Error("Quiz data is null")} />;
|
if (!quizSettings) return <ApologyPage error={new Error("quiz data is null")} />;
|
||||||
|
|
||||||
if (quizSettings.questions.length === 1 && quizSettings?.settings.cfg.noStartPage)
|
if (quizSettings.questions.length === 1 && quizSettings?.settings.cfg.noStartPage)
|
||||||
return <ApologyPage error={new Error("Quiz is empty")} />;
|
return <ApologyPage error={new Error("quiz is empty")} />;
|
||||||
// if (quizSettings.questions.length === 1) return <ApologyPage error={new Error("No questions found")} />;
|
// if (quizSettings.questions.length === 1) return <ApologyPage error={new Error("no questions found")} />;
|
||||||
if (!quizId) return <ApologyPage error={new Error("No quiz id")} />;
|
if (!quizId) return <ApologyPage error={new Error("no quiz id")} />;
|
||||||
|
|
||||||
const quizContainer = (
|
const quizContainer = (
|
||||||
<Box
|
<Box
|
||||||
|
@ -38,7 +38,7 @@ export const Footer = ({ stepNumber, nextButton, prevButton }: FooterProps) => {
|
|||||||
gap: "10px",
|
gap: "10px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{stepNumber !== null && (
|
{stepNumber !== null && settings.status !== "ai" && (
|
||||||
<Box sx={{ flexGrow: 1 }}>
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
<Typography sx={{ color: theme.palette.text.primary }}>
|
<Typography sx={{ color: theme.palette.text.primary }}>
|
||||||
Вопрос {stepNumber} из {questionsAmount}
|
Вопрос {stepNumber} из {questionsAmount}
|
||||||
|
@ -106,7 +106,7 @@ export default function ViewPublicationPage() {
|
|||||||
}
|
}
|
||||||
nextButton={
|
nextButton={
|
||||||
<NextButton
|
<NextButton
|
||||||
isNextButtonEnabled={isNextButtonEnabled}
|
isNextButtonEnabled={settings.status === "ai" || isNextButtonEnabled}
|
||||||
moveToNextQuestion={() => {
|
moveToNextQuestion={() => {
|
||||||
moveToNextQuestion();
|
moveToNextQuestion();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { QuizSettings } from "@model/settingsData";
|
import { QuizSettings } from "@model/settingsData";
|
||||||
import { createContext, useContext } from "react";
|
import { createContext, useContext } from "react";
|
||||||
|
import { AnyTypedQuizQuestion } from "..";
|
||||||
|
|
||||||
export const QuizSettingsContext = createContext<
|
export const QuizSettingsContext = createContext<
|
||||||
| (QuizSettings & {
|
| (QuizSettings & {
|
||||||
|
@ -12,6 +12,7 @@ export interface GetQuizDataResponse {
|
|||||||
due: number;
|
due: number;
|
||||||
delay: number;
|
delay: number;
|
||||||
pausable: boolean;
|
pausable: boolean;
|
||||||
|
status: "start" | "stop" | "ai";
|
||||||
};
|
};
|
||||||
items: {
|
items: {
|
||||||
id: number;
|
id: number;
|
||||||
@ -49,6 +50,7 @@ export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizS
|
|||||||
due: quizDataResponse.settings.due,
|
due: quizDataResponse.settings.due,
|
||||||
delay: quizDataResponse.settings.delay,
|
delay: quizDataResponse.settings.delay,
|
||||||
pausable: quizDataResponse.settings.pausable,
|
pausable: quizDataResponse.settings.pausable,
|
||||||
|
status: quizDataResponse.settings.status,
|
||||||
};
|
};
|
||||||
|
|
||||||
return { cnt: quizDataResponse.cnt, settings, questions: items, show_badge: quizDataResponse.show_badge };
|
return { cnt: quizDataResponse.cnt, settings, questions: items, show_badge: quizDataResponse.show_badge };
|
||||||
|
@ -51,6 +51,7 @@ export type QuizSettingsConfig = {
|
|||||||
delay: number;
|
delay: number;
|
||||||
pausable: boolean;
|
pausable: boolean;
|
||||||
cfg: QuizConfig;
|
cfg: QuizConfig;
|
||||||
|
status: "start" | "stop" | "ai";
|
||||||
};
|
};
|
||||||
|
|
||||||
export type QuizSettings = {
|
export type QuizSettings = {
|
||||||
|
@ -9,10 +9,20 @@ import { useQuizViewStore } from "@stores/quizView";
|
|||||||
|
|
||||||
import { useVkMetricsGoals } from "@/utils/hooks/metrics/useVkMetricsGoals";
|
import { useVkMetricsGoals } from "@/utils/hooks/metrics/useVkMetricsGoals";
|
||||||
import { useYandexMetricsGoals } from "@/utils/hooks/metrics/useYandexMetricsGoals";
|
import { useYandexMetricsGoals } from "@/utils/hooks/metrics/useYandexMetricsGoals";
|
||||||
|
import { AnyTypedQuizQuestion } from "@/index";
|
||||||
|
import { getQuizData } from "@/api/quizRelase";
|
||||||
|
|
||||||
|
let isgetting = false;
|
||||||
|
|
||||||
export function useQuestionFlowControl() {
|
export function useQuestionFlowControl() {
|
||||||
//Получаем инфо о квизе и список вопросов.
|
//Получаем инфо о квизе и список вопросов.
|
||||||
const { settings, questions } = useQuizSettings();
|
const { settings, questions: initialQuestions, quizId } = useQuizSettings();
|
||||||
|
const [questions, setQuestions] = useState(initialQuestions);
|
||||||
|
|
||||||
|
const addQuestion = (question: AnyTypedQuizQuestion) => {
|
||||||
|
setQuestions((prev) => [...prev, question]);
|
||||||
|
};
|
||||||
|
|
||||||
//Когда квиз линейный, не ветвящийся, мы идём по вопросам по их порядковому номеру. Это их page.
|
//Когда квиз линейный, не ветвящийся, мы идём по вопросам по их порядковому номеру. Это их page.
|
||||||
//За корректность page отвечает конструктор квизов. Интересный факт, если в конструкторе удалить из середины вопрос, то случится куча запросов изменения вопросов с изменением этого page
|
//За корректность page отвечает конструктор квизов. Интересный факт, если в конструкторе удалить из середины вопрос, то случится куча запросов изменения вопросов с изменением этого page
|
||||||
const sortedQuestions = useMemo(() => {
|
const sortedQuestions = useMemo(() => {
|
||||||
@ -200,7 +210,12 @@ export function useQuestionFlowControl() {
|
|||||||
}, [prevQuestion]);
|
}, [prevQuestion]);
|
||||||
|
|
||||||
//рычаг управления из визуала в эту функцию
|
//рычаг управления из визуала в эту функцию
|
||||||
const moveToNextQuestion = useCallback(() => {
|
const moveToNextQuestion = useCallback(async () => {
|
||||||
|
if (isgetting) return;
|
||||||
|
isgetting = true;
|
||||||
|
const data = await getQuizData(quizId, settings.status);
|
||||||
|
addQuestion(data.questions[0]);
|
||||||
|
isgetting = false;
|
||||||
if (!nextQuestion) throw new Error("Next question not found");
|
if (!nextQuestion) throw new Error("Next question not found");
|
||||||
|
|
||||||
// Засчитываем переход с вопроса дальше
|
// Засчитываем переход с вопроса дальше
|
||||||
@ -246,7 +261,8 @@ export function useQuestionFlowControl() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
currentQuestion,
|
currentQuestion,
|
||||||
currentQuestionStepNumber: linearQuestionIndex === null ? null : linearQuestionIndex + 1,
|
currentQuestionStepNumber:
|
||||||
|
settings.status === "ai" ? null : linearQuestionIndex === null ? null : linearQuestionIndex + 1,
|
||||||
nextQuestion,
|
nextQuestion,
|
||||||
isNextButtonEnabled,
|
isNextButtonEnabled,
|
||||||
isPreviousButtonEnabled,
|
isPreviousButtonEnabled,
|
||||||
|
Loading…
Reference in New Issue
Block a user