Review cleanups

This commit is contained in:
Connor Yoh 2025-07-23 17:23:25 +01:00
parent 747ecfcbd5
commit da3a0068fe
4 changed files with 63 additions and 92 deletions

View File

@ -1,21 +1,3 @@
export const FROM_FORMATS = {
PDF: 'pdf',
OFFICE: 'office',
IMAGE: 'image',
HTML: 'html',
MARKDOWN: 'markdown',
TEXT: 'text'
} as const;
export const TO_FORMATS = {
PDF: 'pdf',
IMAGE: 'image',
OFFICE_WORD: 'office-word',
OFFICE_PRESENTATION: 'office-presentation',
OFFICE_TEXT: 'office-text',
HTML: 'html',
XML: 'xml'
} as const;
export const COLOR_TYPES = {
COLOR: 'color',
@ -28,14 +10,6 @@ export const OUTPUT_OPTIONS = {
MULTIPLE: 'multiple'
} as const;
export const OFFICE_FORMATS = {
DOCX: 'docx',
ODT: 'odt',
PPTX: 'pptx',
ODP: 'odp',
TXT: 'txt',
RTF: 'rtf'
} as const;
export const CONVERSION_ENDPOINTS = {
'office-pdf': '/api/v1/convert/file/pdf',
@ -63,23 +37,6 @@ export const ENDPOINT_NAMES = {
'markdown-pdf': 'markdown-to-pdf'
} as const;
export const SUPPORTED_CONVERSIONS: Record<string, string[]> = {
[FROM_FORMATS.PDF]: [TO_FORMATS.IMAGE, TO_FORMATS.OFFICE_WORD, TO_FORMATS.OFFICE_PRESENTATION, TO_FORMATS.OFFICE_TEXT, TO_FORMATS.HTML, TO_FORMATS.XML],
[FROM_FORMATS.OFFICE]: [TO_FORMATS.PDF],
[FROM_FORMATS.IMAGE]: [TO_FORMATS.PDF],
[FROM_FORMATS.HTML]: [TO_FORMATS.PDF],
[FROM_FORMATS.MARKDOWN]: [TO_FORMATS.PDF],
[FROM_FORMATS.TEXT]: [TO_FORMATS.PDF]
};
export const FILE_EXTENSIONS = {
[FROM_FORMATS.PDF]: ['pdf'],
[FROM_FORMATS.OFFICE]: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'ods', 'odp'],
[FROM_FORMATS.IMAGE]: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'webp'],
[FROM_FORMATS.HTML]: ['html', 'htm'],
[FROM_FORMATS.MARKDOWN]: ['md'],
[FROM_FORMATS.TEXT]: ['txt', 'rtf']
};
// Grouped file extensions for dropdowns
export const FROM_FORMAT_OPTIONS = [
@ -152,8 +109,5 @@ export const EXTENSION_TO_ENDPOINT: Record<string, Record<string, string>> = {
'txt': { 'pdf': 'file-to-pdf' }, 'rtf': { 'pdf': 'file-to-pdf' }
};
export type FromFormat = typeof FROM_FORMATS[keyof typeof FROM_FORMATS];
export type ToFormat = typeof TO_FORMATS[keyof typeof TO_FORMATS];
export type ColorType = typeof COLOR_TYPES[keyof typeof COLOR_TYPES];
export type OutputOption = typeof OUTPUT_OPTIONS[keyof typeof OUTPUT_OPTIONS];
export type OfficeFormat = typeof OFFICE_FORMATS[keyof typeof OFFICE_FORMATS];

View File

@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useState, useEffect } from 'react';
import axios from 'axios';
import { useTranslation } from 'react-i18next';
import { useFileContext } from '../../../contexts/FileContext';
@ -11,6 +11,7 @@ import {
ENDPOINT_NAMES,
EXTENSION_TO_ENDPOINT
} from '../../../constants/convertConstants';
import { getEndpointUrl } from '../../../utils/convertUtils';
export interface ConvertOperationHook {
executeOperation: (
@ -152,22 +153,8 @@ export const useConvertOperation = (): ConvertOperationHook => {
const { operation, operationId, fileId } = createOperation(parameters, selectedFiles);
const formData = buildFormData(parameters, selectedFiles);
// Get endpoint using constants
const getEndpoint = () => {
const { fromExtension, toExtension } = parameters;
const endpointKey = EXTENSION_TO_ENDPOINT[fromExtension]?.[toExtension];
if (!endpointKey) return '';
// Find the endpoint URL from CONVERSION_ENDPOINTS using the endpoint name
for (const [key, endpoint] of Object.entries(CONVERSION_ENDPOINTS)) {
if (ENDPOINT_NAMES[key as keyof typeof ENDPOINT_NAMES] === endpointKey) {
return endpoint;
}
}
return '';
};
const endpoint = getEndpoint();
// Get endpoint using utility function
const endpoint = getEndpointUrl(parameters.fromExtension, parameters.toExtension);
if (!endpoint) {
setErrorMessage(t("convert.errorNotSupported", { from: parameters.fromExtension, to: parameters.toExtension }));
return;
@ -211,6 +198,11 @@ export const useConvertOperation = (): ConvertOperationHook => {
}, [t, createOperation, buildFormData, recordOperation, markOperationApplied, markOperationFailed, processResults]);
const resetResults = useCallback(() => {
// Clean up blob URLs to prevent memory leaks
if (downloadUrl) {
window.URL.revokeObjectURL(downloadUrl);
}
setFiles([]);
setThumbnails([]);
setIsGeneratingThumbnails(false);
@ -219,12 +211,21 @@ export const useConvertOperation = (): ConvertOperationHook => {
setStatus('');
setErrorMessage(null);
setIsLoading(false);
}, []);
}, [downloadUrl]);
const clearError = useCallback(() => {
setErrorMessage(null);
}, []);
// Cleanup blob URLs on unmount to prevent memory leaks
useEffect(() => {
return () => {
if (downloadUrl) {
window.URL.revokeObjectURL(downloadUrl);
}
};
}, [downloadUrl]);
return {
executeOperation,

View File

@ -1,24 +1,13 @@
import { useState } from 'react';
import {
FROM_FORMATS,
TO_FORMATS,
COLOR_TYPES,
OUTPUT_OPTIONS,
OFFICE_FORMATS,
CONVERSION_ENDPOINTS,
ENDPOINT_NAMES,
SUPPORTED_CONVERSIONS,
FILE_EXTENSIONS,
FROM_FORMAT_OPTIONS,
TO_FORMAT_OPTIONS,
CONVERSION_MATRIX,
EXTENSION_TO_ENDPOINT,
type FromFormat,
type ToFormat,
type ColorType,
type OutputOption,
type OfficeFormat
type OutputOption
} from '../../../constants/convertConstants';
import { getEndpointName as getEndpointNameUtil, getEndpointUrl } from '../../../utils/convertUtils';
export interface ConvertParameters {
fromExtension: string;
@ -83,23 +72,12 @@ export const useConvertParameters = (): ConvertParametersHook => {
const getEndpointName = () => {
const { fromExtension, toExtension } = parameters;
if (!fromExtension || !toExtension) return '';
const endpointKey = EXTENSION_TO_ENDPOINT[fromExtension]?.[toExtension];
return endpointKey || '';
return getEndpointNameUtil(fromExtension, toExtension);
};
const getEndpoint = () => {
const endpointName = getEndpointName();
if (!endpointName) return '';
// Find the endpoint URL from CONVERSION_ENDPOINTS using the endpoint name
for (const [key, endpoint] of Object.entries(CONVERSION_ENDPOINTS)) {
if (ENDPOINT_NAMES[key as keyof typeof ENDPOINT_NAMES] === endpointName) {
return endpoint;
}
}
return '';
const { fromExtension, toExtension } = parameters;
return getEndpointUrl(fromExtension, toExtension);
};
const getAvailableToExtensions = (fromExtension: string) => {

View File

@ -0,0 +1,38 @@
import {
CONVERSION_ENDPOINTS,
ENDPOINT_NAMES,
EXTENSION_TO_ENDPOINT
} from '../constants/convertConstants';
/**
* Resolves the endpoint name for a given conversion
*/
export const getEndpointName = (fromExtension: string, toExtension: string): string => {
if (!fromExtension || !toExtension) return '';
const endpointKey = EXTENSION_TO_ENDPOINT[fromExtension]?.[toExtension];
return endpointKey || '';
};
/**
* Resolves the full endpoint URL for a given conversion
*/
export const getEndpointUrl = (fromExtension: string, toExtension: string): string => {
const endpointName = getEndpointName(fromExtension, toExtension);
if (!endpointName) return '';
// Find the endpoint URL from CONVERSION_ENDPOINTS using the endpoint name
for (const [key, endpoint] of Object.entries(CONVERSION_ENDPOINTS)) {
if (ENDPOINT_NAMES[key as keyof typeof ENDPOINT_NAMES] === endpointName) {
return endpoint;
}
}
return '';
};
/**
* Checks if a conversion is supported
*/
export const isConversionSupported = (fromExtension: string, toExtension: string): boolean => {
return getEndpointName(fromExtension, toExtension) !== '';
};