From b9af3c4ee5168af8ab3853cbe241df5eeda9e7c1 Mon Sep 17 00:00:00 2001 From: Primakov Alexandr Date: Sun, 14 Dec 2025 15:39:45 +0300 Subject: [PATCH] Enhance task management by adding skip functionality in TaskWorkspace and TaskPage. Implement storage methods for tracking skipped tasks, allowing users to navigate to the next task or the first skipped task seamlessly. Update polling manager configuration for improved performance. --- src/components/personal/TaskWorkspace.tsx | 5 +- src/context/ChallengeContext.tsx | 2 +- src/pages/task/TaskPage.tsx | 73 ++++++++++++++++++++--- src/utils/polling.ts | 2 +- src/utils/storage.ts | 45 +++++++++++++- 5 files changed, 112 insertions(+), 15 deletions(-) diff --git a/src/components/personal/TaskWorkspace.tsx b/src/components/personal/TaskWorkspace.tsx index 50fb457..26211e0 100644 --- a/src/components/personal/TaskWorkspace.tsx +++ b/src/components/personal/TaskWorkspace.tsx @@ -18,9 +18,10 @@ import { LearningMaterialViewer } from './LearningMaterialViewer' interface TaskWorkspaceProps { task: ChallengeTask onTaskComplete?: () => void + onTaskSkip?: () => void } -export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => { +export const TaskWorkspace = ({ task, onTaskComplete, onTaskSkip }: TaskWorkspaceProps) => { const { refreshStats } = useChallenge() const { result, setResult, submit, queueStatus, finalSubmission, isSubmitting } = useSubmission({ taskId: task.id, @@ -397,7 +398,7 @@ export const TaskWorkspace = ({ task, onTaskComplete }: TaskWorkspaceProps) => { {!isAccepted && ( <> @@ -202,7 +259,7 @@ export const TaskPage = () => { - + diff --git a/src/utils/polling.ts b/src/utils/polling.ts index 5558d11..e09affe 100644 --- a/src/utils/polling.ts +++ b/src/utils/polling.ts @@ -16,7 +16,7 @@ export class PollingManager { constructor(options: PollingOptions = {}) { this.currentDelay = options.initialDelay ?? 2000 this.maxDelay = options.maxDelay ?? 10000 - this.multiplier = options.multiplier ?? 1.5 + this.multiplier = options.multiplier ?? 1.01 } async start(callback: PollCallback) { diff --git a/src/utils/storage.ts b/src/utils/storage.ts index f5cea93..10a631f 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -16,8 +16,9 @@ export const STORAGE_KEYS = { SELECTED_TASK_ID: 'challengeSelectedTaskId', } as const -// Вспомогательная функция для ключа прогресса цепочки +// Вспомогательные функции для ключей const getFurthestTaskKey = (chainId: string) => `challengeFurthestTask_${chainId}` +const getSkippedTasksKey = (chainId: string) => `challengeSkippedTasks_${chainId}` // Получение значений export const storage = { @@ -121,11 +122,11 @@ export const storage = { // Очистка всех прогрессов по цепочкам clearAllChainProgress: (): void => { if (!isBrowser()) return - // Перебираем все ключи localStorage и удаляем те, что начинаются с challengeFurthestTask_ + // Перебираем все ключи localStorage и удаляем те, что начинаются с challengeFurthestTask_ или challengeSkippedTasks_ const keysToRemove: string[] = [] for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i) - if (key && key.startsWith('challengeFurthestTask_')) { + if (key && (key.startsWith('challengeFurthestTask_') || key.startsWith('challengeSkippedTasks_'))) { keysToRemove.push(key) } } @@ -161,5 +162,43 @@ export const storage = { if (!isBrowser()) return localStorage.removeItem(getFurthestTaskKey(chainId)) }, + + // Получение пропущенных заданий для цепочки + getSkippedTasks: (chainId: string): string[] => { + if (!isBrowser()) return [] + const value = localStorage.getItem(getSkippedTasksKey(chainId)) + return value ? JSON.parse(value) : [] + }, + + // Добавление задания в список пропущенных + addSkippedTask: (chainId: string, taskId: string): void => { + if (!isBrowser()) return + const skipped = storage.getSkippedTasks(chainId) + if (!skipped.includes(taskId)) { + skipped.push(taskId) + localStorage.setItem(getSkippedTasksKey(chainId), JSON.stringify(skipped)) + } + }, + + // Удаление задания из списка пропущенных (когда оно выполнено) + removeSkippedTask: (chainId: string, taskId: string): void => { + if (!isBrowser()) return + const skipped = storage.getSkippedTasks(chainId) + const filtered = skipped.filter(id => id !== taskId) + localStorage.setItem(getSkippedTasksKey(chainId), JSON.stringify(filtered)) + }, + + // Проверка, пропущено ли задание + isTaskSkipped: (chainId: string, taskId: string): boolean => { + if (!isBrowser()) return false + const skipped = storage.getSkippedTasks(chainId) + return skipped.includes(taskId) + }, + + // Очистка всех пропущенных заданий цепочки + clearSkippedTasks: (chainId: string): void => { + if (!isBrowser()) return + localStorage.removeItem(getSkippedTasksKey(chainId)) + }, }