mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 03:20:46 +02:00
Preserve local paths for desktop saves (#5543)
# Summary - Adds desktop file tracking: local paths are preserved and save buttons now work as expcted (doing Save/Save As as appropriate) - Adds logic to track whether files are 'dirty' (they've been modified by some tool, and not saved to disk yet). - Improves file state UX (dirty vs saved) and close warnings - Web behaviour should be unaffected by these changes ## Indicators Files now have indicators in desktop mode to tell you their state. ### File up-to-date with disk <img width="318" height="393" alt="image" src="https://github.com/user-attachments/assets/06325f9a-afd7-4c2f-8a5b-6d11e3093115" /> ### File modified by a tool but not saved to disk yet <img width="357" height="385" alt="image" src="https://github.com/user-attachments/assets/1a7716d9-c6f7-4d13-be0d-c1de6493954b" /> ### File not tracked on disk <img width="312" height="379" alt="image" src="https://github.com/user-attachments/assets/9cffe300-bd9a-4e19-97c7-9b98bebefacc" /> # Limitations - It's a bit weird that we still have files stored in indexeddb in the app, which are still loadable. We might want to change this behaviour in the future - Viewer's Save doesn't persist to disk. I've left that out here because it'd need a lot of testing to make sure the logic's right with making sure you can leave the Viewer with applying the changes to the PDF _without_ saving to disk - There's no current way to do Save As on a file that has already been persisted to disk - it's only ever Save. Similarly, there's no way to duplicate a file. --------- Co-authored-by: James Brunton <[email protected]> Co-authored-by: James Brunton <[email protected]>
This commit is contained in:
co-authored by
James Brunton
James Brunton
parent
946196de43
commit
b8ce4e47c1
@@ -4,6 +4,7 @@
|
||||
|
||||
import { AutomationConfig } from '@app/types/automation';
|
||||
import { ToolRegistry } from '@app/data/toolsTaxonomy';
|
||||
import { downloadFile } from '@app/services/downloadService';
|
||||
import { ToolId } from '@app/types/toolId';
|
||||
|
||||
/**
|
||||
@@ -95,16 +96,5 @@ export function downloadFolderScanningConfig(
|
||||
const config = convertToFolderScanningConfig(automation, toolRegistry);
|
||||
const json = JSON.stringify(config, null, 2);
|
||||
const blob = new Blob([json], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `${automation.name}.json`;
|
||||
a.style.display = 'none';
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
URL.revokeObjectURL(url);
|
||||
void downloadFile({ data: blob, filename: `${automation.name}.json` });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { StirlingFileStub } from '@app/types/fileContext';
|
||||
import { fileStorage } from '@app/services/fileStorage';
|
||||
import { zipFileService } from '@app/services/zipFileService';
|
||||
import { downloadFile } from '@app/services/downloadService';
|
||||
|
||||
/**
|
||||
* Downloads a blob as a file using browser download API
|
||||
@@ -8,17 +9,7 @@ import { zipFileService } from '@app/services/zipFileService';
|
||||
* @param filename - The filename for the download
|
||||
*/
|
||||
export function downloadBlob(blob: Blob, filename: string): void {
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
// Clean up the blob URL
|
||||
URL.revokeObjectURL(url);
|
||||
void downloadFile({ data: blob, filename });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,8 +25,11 @@ export async function downloadFileFromStorage(file: StirlingFileStub): Promise<v
|
||||
throw new Error(`File "${file.name}" not found in storage`);
|
||||
}
|
||||
|
||||
// StirlingFile is already a File object, just download it
|
||||
downloadBlob(stirlingFile, stirlingFile.name);
|
||||
await downloadFile({
|
||||
data: stirlingFile,
|
||||
filename: stirlingFile.name,
|
||||
localPath: file.localFilePath
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +74,7 @@ export async function downloadFilesAsZip(files: StirlingFileStub[], zipFilename?
|
||||
|
||||
// Create and download ZIP
|
||||
const { zipFile } = await zipFileService.createZipFromFiles(filesToZip, finalZipFilename);
|
||||
downloadBlob(zipFile, finalZipFilename);
|
||||
await downloadFile({ data: zipFile, filename: finalZipFilename });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +114,7 @@ export async function downloadFiles(
|
||||
* @param filename - Optional custom filename
|
||||
*/
|
||||
export function downloadFileObject(file: File, filename?: string): void {
|
||||
downloadBlob(file, filename || file.name);
|
||||
void downloadFile({ data: file, filename: filename || file.name });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +129,7 @@ export function downloadTextAsFile(
|
||||
mimeType: string = 'text/plain'
|
||||
): void {
|
||||
const blob = new Blob([content], { type: mimeType });
|
||||
downloadBlob(blob, filename);
|
||||
void downloadFile({ data: blob, filename });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export function getDocumentFileDialogFilter() {
|
||||
return [{
|
||||
name: 'Documents',
|
||||
extensions: ['pdf', 'jpg', 'jpeg', 'png', 'gif', 'tiff', 'bmp', 'html', 'zip']
|
||||
}];
|
||||
}
|
||||
Reference in New Issue
Block a user