mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-01 20:10:35 +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:
parent
eee17d4d19
commit
43d4b46b31
1569
frontend/package-lock.json
generated
1569
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -43,13 +43,13 @@
|
||||
"@supabase/supabase-js": "^2.47.13",
|
||||
"@tailwindcss/postcss": "^4.1.13",
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-fs": "^2.4.0",
|
||||
"@tauri-apps/plugin-http": "^2.5.4",
|
||||
"@tauri-apps/plugin-shell": "^2.3.3",
|
||||
"@tauri-apps/api": "^2.9.1",
|
||||
"@tauri-apps/plugin-fs": "^2.4.5",
|
||||
"@tauri-apps/plugin-http": "^2.5.6",
|
||||
"@tauri-apps/plugin-shell": "^2.3.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"axios": "^1.12.2",
|
||||
"globals": "^17.0.0",
|
||||
"axios": "^1.13.2",
|
||||
"globals": "^17.1.0",
|
||||
"i18next": "^25.5.2",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"jszip": "^3.10.1",
|
||||
@ -58,7 +58,7 @@
|
||||
"pdfjs-dist": "^5.4.149",
|
||||
"peerjs": "^1.5.5",
|
||||
"posthog-js": "^1.268.0",
|
||||
"qrcode.react": "^4.1.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-i18next": "^15.7.3",
|
||||
@ -126,10 +126,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@iconify-json/material-symbols": "^1.2.48",
|
||||
"@iconify/utils": "^3.0.2",
|
||||
"@iconify-json/material-symbols": "^1.2.53",
|
||||
"@iconify/utils": "^3.1.0",
|
||||
"@playwright/test": "^1.55.0",
|
||||
"@tauri-apps/cli": "^2.5.0",
|
||||
"@tauri-apps/cli": "^2.9.6",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
|
||||
1091
frontend/src-tauri/Cargo.lock
generated
1091
frontend/src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -18,21 +18,21 @@ name = "app_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.2.0", features = [] }
|
||||
tauri-build = { version = "2.5.3", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
log = "0.4"
|
||||
tauri = { version = "2.9.0", features = [ "devtools"] }
|
||||
tauri-plugin-log = "2.0.0-rc"
|
||||
tauri-plugin-shell = "2.1.0"
|
||||
tauri-plugin-fs = "2.4.4"
|
||||
tauri-plugin-http = { version = "2.4.4", features = ["dangerous-settings"] }
|
||||
tauri-plugin-single-instance = { version = "2.3.6", features = ["deep-link"] }
|
||||
tauri-plugin-store = "2.1.0"
|
||||
tauri-plugin-opener = "2.0.0"
|
||||
tauri-plugin-deep-link = "2.4.5"
|
||||
tauri-plugin-log = "2.8.0"
|
||||
tauri-plugin-shell = "2.3.4"
|
||||
tauri-plugin-fs = "2.4.5"
|
||||
tauri-plugin-http = { version = "2.5.6", features = ["dangerous-settings"] }
|
||||
tauri-plugin-single-instance = { version = "2.3.7", features = ["deep-link"] }
|
||||
tauri-plugin-store = "2.4.2"
|
||||
tauri-plugin-opener = "2.5.3"
|
||||
tauri-plugin-deep-link = "2.4.6"
|
||||
keyring = { version = "3.6.1", features = ["apple-native", "windows-native"] }
|
||||
tokio = { version = "1.0", features = ["time", "sync"] }
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
|
||||
@ -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}`);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user