137 lines
3.9 KiB
TypeScript
Raw Normal View History

Feature/v2/shared tool hooks (#4134) # Description of Changes <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Reece Browne <you@example.com>
2025-08-08 16:01:56 +01:00
import { useReducer, useCallback } from 'react';
export interface ProcessingProgress {
current: number;
total: number;
currentFileName?: string;
}
export interface OperationState {
files: File[];
thumbnails: string[];
isGeneratingThumbnails: boolean;
downloadUrl: string | null;
downloadFilename: string;
isLoading: boolean;
status: string;
errorMessage: string | null;
progress: ProcessingProgress | null;
}
type OperationAction =
| { type: 'SET_LOADING'; payload: boolean }
| { type: 'SET_FILES'; payload: File[] }
| { type: 'SET_THUMBNAILS'; payload: string[] }
| { type: 'SET_GENERATING_THUMBNAILS'; payload: boolean }
| { type: 'SET_DOWNLOAD_INFO'; payload: { url: string | null; filename: string } }
| { type: 'SET_STATUS'; payload: string }
| { type: 'SET_ERROR'; payload: string | null }
| { type: 'SET_PROGRESS'; payload: ProcessingProgress | null }
| { type: 'RESET_RESULTS' }
| { type: 'CLEAR_ERROR' };
const initialState: OperationState = {
files: [],
thumbnails: [],
isGeneratingThumbnails: false,
downloadUrl: null,
downloadFilename: '',
isLoading: false,
status: '',
errorMessage: null,
progress: null,
};
const operationReducer = (state: OperationState, action: OperationAction): OperationState => {
switch (action.type) {
case 'SET_LOADING':
return { ...state, isLoading: action.payload };
case 'SET_FILES':
return { ...state, files: action.payload };
case 'SET_THUMBNAILS':
return { ...state, thumbnails: action.payload };
case 'SET_GENERATING_THUMBNAILS':
return { ...state, isGeneratingThumbnails: action.payload };
case 'SET_DOWNLOAD_INFO':
return {
...state,
downloadUrl: action.payload.url,
downloadFilename: action.payload.filename
};
case 'SET_STATUS':
return { ...state, status: action.payload };
case 'SET_ERROR':
return { ...state, errorMessage: action.payload };
case 'SET_PROGRESS':
return { ...state, progress: action.payload };
case 'RESET_RESULTS':
return {
...initialState,
isLoading: state.isLoading, // Preserve loading state during reset
};
case 'CLEAR_ERROR':
return { ...state, errorMessage: null };
default:
return state;
}
};
export const useToolState = () => {
const [state, dispatch] = useReducer(operationReducer, initialState);
const setLoading = useCallback((loading: boolean) => {
dispatch({ type: 'SET_LOADING', payload: loading });
}, []);
const setFiles = useCallback((files: File[]) => {
dispatch({ type: 'SET_FILES', payload: files });
}, []);
const setThumbnails = useCallback((thumbnails: string[]) => {
dispatch({ type: 'SET_THUMBNAILS', payload: thumbnails });
}, []);
const setGeneratingThumbnails = useCallback((generating: boolean) => {
dispatch({ type: 'SET_GENERATING_THUMBNAILS', payload: generating });
}, []);
const setDownloadInfo = useCallback((url: string | null, filename: string) => {
dispatch({ type: 'SET_DOWNLOAD_INFO', payload: { url, filename } });
}, []);
const setStatus = useCallback((status: string) => {
dispatch({ type: 'SET_STATUS', payload: status });
}, []);
const setError = useCallback((error: string | null) => {
dispatch({ type: 'SET_ERROR', payload: error });
}, []);
const setProgress = useCallback((progress: ProcessingProgress | null) => {
dispatch({ type: 'SET_PROGRESS', payload: progress });
}, []);
const resetResults = useCallback(() => {
dispatch({ type: 'RESET_RESULTS' });
}, []);
const clearError = useCallback(() => {
dispatch({ type: 'CLEAR_ERROR' });
}, []);
return {
state,
actions: {
setLoading,
setFiles,
setThumbnails,
setGeneratingThumbnails,
setDownloadInfo,
setStatus,
setError,
setProgress,
resetResults,
clearError,
},
};
};