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