Files
challenge-pl/src/utils/storage.ts

205 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Централизованная работа с localStorage
* Все ключи и операции в одном месте
*/
import { clearAllFinalAnswers, listDrafts, clearDraft } from './drafts'
const isBrowser = () => typeof window !== 'undefined'
// Ключи localStorage
export const STORAGE_KEYS = {
USER_ID: 'challengeUserId',
NICKNAME: 'challengeNickname',
WORKPLACE_NUMBER: 'challengeWorkplaceNumber',
SELECTED_CHAIN_ID: 'challengeSelectedChainId',
SELECTED_TASK_ID: 'challengeSelectedTaskId',
} as const
// Вспомогательные функции для ключей
const getFurthestTaskKey = (chainId: string) => `challengeFurthestTask_${chainId}`
const getSkippedTasksKey = (chainId: string) => `challengeSkippedTasks_${chainId}`
// Получение значений
export const storage = {
getUserId: (): string | null => {
if (!isBrowser()) return null
return localStorage.getItem(STORAGE_KEYS.USER_ID)
},
getNickname: (): string | null => {
if (!isBrowser()) return null
return localStorage.getItem(STORAGE_KEYS.NICKNAME)
},
getWorkplaceNumber: (): string | null => {
if (!isBrowser()) return null
return localStorage.getItem(STORAGE_KEYS.WORKPLACE_NUMBER)
},
getSelectedChainId: (): string | null => {
if (!isBrowser()) return null
return localStorage.getItem(STORAGE_KEYS.SELECTED_CHAIN_ID)
},
getSelectedTaskId: (): string | null => {
if (!isBrowser()) return null
return localStorage.getItem(STORAGE_KEYS.SELECTED_TASK_ID)
},
// Установка значений
setUserId: (value: string): void => {
if (!isBrowser()) return
localStorage.setItem(STORAGE_KEYS.USER_ID, value)
},
setNickname: (value: string): void => {
if (!isBrowser()) return
localStorage.setItem(STORAGE_KEYS.NICKNAME, value)
},
setWorkplaceNumber: (value: string): void => {
if (!isBrowser()) return
localStorage.setItem(STORAGE_KEYS.WORKPLACE_NUMBER, value)
},
setSelectedChainId: (value: string): void => {
if (!isBrowser()) return
localStorage.setItem(STORAGE_KEYS.SELECTED_CHAIN_ID, value)
},
setSelectedTaskId: (value: string): void => {
if (!isBrowser()) return
localStorage.setItem(STORAGE_KEYS.SELECTED_TASK_ID, value)
},
// Удаление значений
removeUserId: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.USER_ID)
},
removeNickname: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.NICKNAME)
},
removeWorkplaceNumber: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.WORKPLACE_NUMBER)
},
removeSelectedChainId: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.SELECTED_CHAIN_ID)
},
removeSelectedTaskId: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.SELECTED_TASK_ID)
},
// Полная очистка при выходе (кроме номера рабочего места)
clearAll: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.USER_ID)
localStorage.removeItem(STORAGE_KEYS.NICKNAME)
// Номер рабочего места НЕ удаляем
localStorage.removeItem(STORAGE_KEYS.SELECTED_CHAIN_ID)
localStorage.removeItem(STORAGE_KEYS.SELECTED_TASK_ID)
// Очищаем все прогрессы по цепочкам
storage.clearAllChainProgress()
// Очищаем все финальные ответы
clearAllFinalAnswers()
// Очищаем все черновики
const drafts = listDrafts()
drafts.forEach(taskId => clearDraft(taskId))
},
// Очистка всех прогрессов по цепочкам
clearAllChainProgress: (): void => {
if (!isBrowser()) return
// Перебираем все ключи localStorage и удаляем те, что начинаются с challengeFurthestTask_ или challengeSkippedTasks_
const keysToRemove: string[] = []
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
if (key && (key.startsWith('challengeFurthestTask_') || key.startsWith('challengeSkippedTasks_'))) {
keysToRemove.push(key)
}
}
keysToRemove.forEach(key => localStorage.removeItem(key))
},
// Очистка данных сессии (цепочка, задание) без выхода
clearSessionData: (): void => {
if (!isBrowser()) return
localStorage.removeItem(STORAGE_KEYS.SELECTED_CHAIN_ID)
localStorage.removeItem(STORAGE_KEYS.SELECTED_TASK_ID)
},
// Получение самого дальнего достигнутого индекса задания в цепочке
getFurthestTaskIndex: (chainId: string): number => {
if (!isBrowser()) return 0
const value = localStorage.getItem(getFurthestTaskKey(chainId))
return value ? parseInt(value, 10) : 0
},
// Установка самого дальнего достигнутого индекса задания
setFurthestTaskIndex: (chainId: string, index: number): void => {
if (!isBrowser()) return
const current = storage.getFurthestTaskIndex(chainId)
// Обновляем только если новый индекс больше текущего
if (index > current) {
localStorage.setItem(getFurthestTaskKey(chainId), index.toString())
}
},
// Очистка прогресса цепочки
clearChainProgress: (chainId: string): void => {
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))
},
}