mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-03-04 02:20:19 +01:00
deps(frontend, tauri): update Tauri, Rust crates, and frontend dependencies (#5569)
# Description of Changes This pull request primarily updates dependencies for both the frontend JavaScript and Rust (Tauri) codebases, and refactors the `MobileUploadModal` component to consistently use a centralized API client for backend communication. The refactor improves code consistency, error handling, and logging in the file upload workflow. **Dependency updates** * Updated several Tauri-related dependencies in both `frontend/package.json` and `frontend/src-tauri/Cargo.toml` to their latest versions, including `@tauri-apps/api`, `@tauri-apps/plugin-fs`, `@tauri-apps/plugin-http`, `@tauri-apps/plugin-shell`, and associated Rust crates. This ensures better compatibility, security, and access to new features. [[1]](diffhunk://#diff-da6498268e99511d9ba0df3c13e439d10556a812881c9d03955b2ef7c6c1c655L46-R49) [[2]](diffhunk://#diff-da6498268e99511d9ba0df3c13e439d10556a812881c9d03955b2ef7c6c1c655L129-R132) [[3]](diffhunk://#diff-91e702206f8c6459b43ae72dbd6abfed8104de661dd239d13956985210f67fd0L21-R35) * Updated `@iconify-json/material-symbols` and `@tauri-apps/cli` in `package.json` for improved icon support and build tooling. **Refactor: API client usage in `MobileUploadModal`** * Replaced all direct `fetch` calls in `MobileUploadModal.tsx` with the centralized `apiClient`, standardizing backend requests and improving maintainability. [[1]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aR13) [[2]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL84-R98) [[3]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL116-R122) [[4]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL130-R138) [[5]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL160-R177) [[6]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL187-R207) * Improved error handling, status checks, and logging throughout the upload and session management flow, making debugging easier and the user experience more robust. [[1]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL84-R98) [[2]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL130-R138) [[3]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL148-R153) [[4]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL160-R177) [[5]](diffhunk://#diff-fafb4b340343062aba7b763dea5e6e13e0e330ab2ac7dfd04a2032ba79620c8aL187-R207) **Session cleanup improvements** * Ensured that mobile scanner sessions are reliably cleaned up both when the modal closes and when the component unmounts, using the `apiClient` and React's effect cleanup mechanism. --- ## 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) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### 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: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
|
||||
import { Z_INDEX_OVER_FILE_MANAGER_MODAL } from '@app/styles/zIndex';
|
||||
import { withBasePath } from '@app/constants/app';
|
||||
import { convertImageToPdf, isImageFile } from '@app/utils/imageToPdfUtils';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
|
||||
interface MobileUploadModalProps {
|
||||
opened: boolean;
|
||||
@@ -75,26 +76,27 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
|
||||
// Use configured frontendUrl if set, otherwise use current origin
|
||||
// Combine with base path and mobile-scanner route
|
||||
const frontendUrl = config?.frontendUrl || window.location.origin;
|
||||
const baseUrl = localStorage.getItem('server_url') || '';
|
||||
const frontendUrl = baseUrl || config?.frontendUrl || window.location.origin;
|
||||
const mobileUrl = `${frontendUrl}${withBasePath('/mobile-scanner')}?session=${sessionId}`;
|
||||
|
||||
// Create session on backend
|
||||
const createSession = useCallback(async (newSessionId: string) => {
|
||||
try {
|
||||
const response = await fetch(`/api/v1/mobile-scanner/create-session/${newSessionId}`, {
|
||||
method: 'POST'
|
||||
const response = await apiClient.post<SessionInfo>(`/api/v1/mobile-scanner/create-session/${newSessionId}`, undefined, {
|
||||
responseType: 'json',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
if (!response.status || response.status !== 200) {
|
||||
throw new Error('Failed to create session');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const data = response.data;
|
||||
setSessionInfo(data);
|
||||
setError(null);
|
||||
console.log('Session created:', data);
|
||||
console.log('[MobileUploadModal] Session created:', data);
|
||||
} catch (err) {
|
||||
console.error('Failed to create session:', err);
|
||||
console.error('[MobileUploadModal] Failed to create session:', err);
|
||||
setError(t('mobileUpload.sessionCreateError', 'Failed to create session'));
|
||||
}
|
||||
}, [t]);
|
||||
@@ -113,12 +115,12 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
if (!opened) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/v1/mobile-scanner/files/${sessionId}`);
|
||||
if (!response.ok) {
|
||||
const response = await apiClient.get(`/api/v1/mobile-scanner/files/${sessionId}`);
|
||||
if (!response.status || response.status !== 200) {
|
||||
throw new Error('Failed to check for files');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const data = response.data;
|
||||
const files = data.files || [];
|
||||
|
||||
// Download only files we haven't processed yet
|
||||
@@ -127,12 +129,14 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
if (newFiles.length > 0) {
|
||||
for (const fileMetadata of newFiles) {
|
||||
try {
|
||||
const downloadResponse = await fetch(
|
||||
`/api/v1/mobile-scanner/download/${sessionId}/${fileMetadata.filename}`
|
||||
const downloadResponse = await apiClient.get(
|
||||
`/api/v1/mobile-scanner/download/${sessionId}/${fileMetadata.filename}`, {
|
||||
responseType: 'blob',
|
||||
}
|
||||
);
|
||||
|
||||
if (downloadResponse.ok) {
|
||||
const blob = await downloadResponse.blob();
|
||||
if (downloadResponse.status === 200) {
|
||||
const blob = downloadResponse.data;
|
||||
let file = new File([blob], fileMetadata.filename, {
|
||||
type: fileMetadata.contentType || 'image/jpeg'
|
||||
});
|
||||
@@ -145,9 +149,9 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
pageFormat: config?.mobileScannerPageFormat as 'keep' | 'A4' | 'letter' | undefined,
|
||||
stretchToFit: config?.mobileScannerStretchToFit,
|
||||
});
|
||||
console.log('Converted image to PDF:', file.name);
|
||||
console.log('[MobileUploadModal] Converted image to PDF:', file.name);
|
||||
} catch (convertError) {
|
||||
console.warn('Failed to convert image to PDF, using original file:', convertError);
|
||||
console.warn('[MobileUploadModal] Failed to convert image to PDF, using original file:', convertError);
|
||||
// Continue with original image file if conversion fails
|
||||
}
|
||||
}
|
||||
@@ -157,21 +161,21 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
onFilesReceived([file]);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to download file:', fileMetadata.filename, err);
|
||||
console.error('[MobileUploadModal] Failed to download file:', fileMetadata.filename, err);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the entire session immediately after downloading all files
|
||||
// This ensures files are only on server for ~1 second
|
||||
try {
|
||||
await fetch(`/api/v1/mobile-scanner/session/${sessionId}`, { method: 'DELETE' });
|
||||
console.log('Session cleaned up after file download');
|
||||
await apiClient.delete(`/api/v1/mobile-scanner/session/${sessionId}`);
|
||||
console.log('[MobileUploadModal] Session cleaned up after file download');
|
||||
} catch (cleanupErr) {
|
||||
console.warn('Failed to cleanup session after download:', cleanupErr);
|
||||
console.warn('[MobileUploadModal] Failed to cleanup session after download:', cleanupErr);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error polling for files:', err);
|
||||
console.error('[MobileUploadModal] Error polling for files:', err);
|
||||
setError(t('mobileUpload.pollingError', 'Error checking for files'));
|
||||
}
|
||||
}, [opened, sessionId, onFilesReceived, t]);
|
||||
@@ -184,14 +188,24 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
setError(null);
|
||||
setShowExpiryWarning(false);
|
||||
processedFiles.current.clear();
|
||||
} else {
|
||||
// Clean up session when modal closes
|
||||
if (sessionId) {
|
||||
fetch(`/api/v1/mobile-scanner/session/${sessionId}`, { method: 'DELETE' })
|
||||
.catch(err => console.warn('Failed to cleanup session on close:', err));
|
||||
}
|
||||
}
|
||||
}, [opened]); // Only run when opened changes
|
||||
}, [opened, sessionId]); // Only run when opened changes
|
||||
|
||||
useEffect(() => {
|
||||
if (!opened) return;
|
||||
|
||||
createSession(sessionId);
|
||||
setFilesReceived(0);
|
||||
setError(null);
|
||||
setShowExpiryWarning(false);
|
||||
processedFiles.current.clear();
|
||||
|
||||
return () => {
|
||||
console.log('Cleaning up session on unmount/close:', sessionId);
|
||||
apiClient.delete(`/api/v1/mobile-scanner/session/${sessionId}`)
|
||||
.catch(err => console.warn('[MobileUploadModal] Cleanup failed:', err));
|
||||
};
|
||||
}, [opened, sessionId, createSession]);
|
||||
|
||||
// Start polling for files when modal opens
|
||||
useEffect(() => {
|
||||
|
||||
@@ -45,6 +45,8 @@ export function setupApiInterceptors(client: AxiosInstance): void {
|
||||
extendedConfig.url = `${baseUrl}${extendedConfig.url}`;
|
||||
}
|
||||
|
||||
localStorage.setItem('server_url', baseUrl);
|
||||
|
||||
// Debug logging
|
||||
console.debug(`[apiClientSetup] Request to: ${extendedConfig.url}`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user