/* eslint-disable react-refresh/only-export-components */ import { createContext, useContext, useMemo, useReducer } from 'react' function getDefaultActiveTable(annotation, activePage) { const tables = annotation?.tables || [] const first = tables.find((table) => (table.page || 0) === activePage) return first?.table_id ?? null } function buildInitialState(annotation) { const activePage = 0 return { activePage, activeCell: null, activeTable: getDefaultActiveTable(annotation, activePage), tdThreshold: 0, selectionPadding: 0, showTableGrid: true, showTextBoxes: false, showHeatmap: false, toast: null, errorCount: 0, undoStack: [], redoStack: [], activeTool: 'pointer', selection: null, cellSelection: null, } } function studioReducer(state, action) { switch (action.type) { case 'setActivePage': return { ...state, activePage: action.page, } case 'setActiveTable': return { ...state, activeTable: action.tableId, } case 'setActiveCell': return { ...state, activeCell: action.cell, } case 'setThreshold': return { ...state, tdThreshold: action.value, } case 'setPadding': return { ...state, selectionPadding: action.value, } case 'toggleFlag': return { ...state, [action.flag]: !state[action.flag], } case 'showToast': return { ...state, toast: action.toast, } case 'clearToast': return { ...state, toast: null, } case 'incrementErrors': return { ...state, errorCount: state.errorCount + 1, } case 'recordEdit': return { ...state, undoStack: [...state.undoStack, action.edit], redoStack: [], } case 'completeUndo': if (!state.undoStack.length) { return state } return { ...state, undoStack: state.undoStack.slice(0, -1), redoStack: [...state.redoStack, state.undoStack[state.undoStack.length - 1]], } case 'completeRedo': if (!state.redoStack.length) { return state } return { ...state, undoStack: [...state.undoStack, state.redoStack[state.redoStack.length - 1]], redoStack: state.redoStack.slice(0, -1), } case 'setTool': return { ...state, activeTool: action.tool, selection: null, } case 'setSelection': return { ...state, selection: action.selection, } case 'setCellSelection': return { ...state, cellSelection: action.selection, } default: return state } } const StudioContext = createContext(null) export function StudioProvider({ annotation, children }) { const [state, dispatch] = useReducer(studioReducer, annotation, buildInitialState) const value = useMemo(() => ({ state, dispatch }), [state]) return {children} } export function useStudio() { const value = useContext(StudioContext) if (!value) { throw new Error('useStudio must be used within StudioProvider') } return value }