import { parseMemoryMB, parseTimeMS } from '@hydrooj/utils/lib/common'; import type { ProblemConfigFile } from 'hydrooj/src/interface'; import yaml from 'js-yaml'; import { cloneDeep } from 'lodash'; type State = ProblemConfigFile & { __loaded: boolean }; export default function reducer(state = { type: 'default', __loaded: false } as State, action): State { switch (action.type) { case 'CONFIG_LOAD_FULFILLED': { return { ...state, ...yaml.load(action.payload.config) as object, __loaded: true }; } case 'CONFIG_FORM_UPDATE': { const next = { ...state, [action.key]: action.value }; if (action.key === 'score' && action.value) next.score = +next.score; if (action.key === 'checker_type' && action.value === 'other') next.checker_type = 'syzoj'; if (!action.value || (typeof action.value === 'object' && !action.value.join(''))) delete next[action.key]; return next; } case 'CONFIG_CODE_UPDATE': { try { return { ...state, ...yaml.load(action.payload) as object }; } catch { return state; } } case 'CONFIG_AUTOCASES_UPDATE': { const next = { ...state }; const { subtasks } = action; for (const subtask of subtasks) { if (subtask.time === parseTimeMS(state.time || '1s')) delete subtask.time; if (subtask.memory === parseMemoryMB(state.memory || '256m')) delete subtask.memory; if (subtask.time) subtask.time += 'ms'; if (subtask.memory) subtask.memory += 'MB'; } if (subtasks.length === 0) next.subtasks = []; else { next.subtasks = subtasks.map((subtask) => ( { ...subtask, ...{ cases: subtask.cases.map((i) => ({ input: i.input, output: i.output })) } })); } return next; } case 'CONFIG_SUBTASK_UPDATE': { const subtasks = cloneDeep(state.subtasks); const subsubtasks = cloneDeep(state.subtasks[action.id]); if (action.value !== '' && ['score', 'id'].includes(action.key)) action.value = +action.value; if (action.key === 'if' && action.value.join('') !== '') action.value = action.value.map((i) => +i); if (action.key.split('-')[0] === 'cases') { if (action.key === 'cases-add') subsubtasks.cases.push(action.value); else if (action.key === 'cases-edit') { if (action.value === '' && !['input', 'output'].includes(action.casesKey)) delete subsubtasks.cases[action.casesId][action.casesKey]; else subsubtasks.cases[action.casesId][action.casesKey] = action.value; } else if (action.key === 'cases-delete') { subsubtasks.cases = subsubtasks.cases.filter((k, v) => v !== action.value); } } else if (action.key === 'add') { return { ...state, subtasks: [...subtasks, { time: state.time || '1s', memory: state.memory || '256m', cases: [] }] }; } else if (action.key === 'delete') return { ...state, subtasks: subtasks.filter((k, v) => v !== action.id) }; else { if (action.value === '' || (action.key === 'if' && action.value.join('') === '')) delete subsubtasks[action.key]; else subsubtasks[action.key] = action.value; } subtasks[action.id] = subsubtasks; return { ...state, subtasks }; } default: return state; } }