Feature/v2/toggle_for_auto_unzip (#4584)

## default 
<img width="1012" height="627"
alt="{BF57458D-50A6-4057-94F1-D6AB4628EFD8}"
src="https://github.com/user-attachments/assets/85e550ab-0aed-4341-be95-d5d3bc7146db"
/>

## disabled
<img width="1141" height="620"
alt="{140DB87B-05CF-4E0E-A14A-ED15075BD2EE}"
src="https://github.com/user-attachments/assets/e0f56e84-fb9d-4787-b5cb-ba7c5a54b1e1"
/>

## unzip options
<img width="530" height="255"
alt="{482CE185-73D5-4D90-91BB-B9305C711391}"
src="https://github.com/user-attachments/assets/609b18ee-4eae-4cee-afc1-5db01f9d1088"
/>
<img width="579" height="473"
alt="{4DFCA96D-792D-4370-8C62-4BA42C9F1A5F}"
src="https://github.com/user-attachments/assets/c67fa4af-04ef-41df-9420-65ce4247e25b"
/>

## pop up and maintains version metadata
<img width="1071" height="1220"
alt="{7F2A785C-5717-4A79-9D45-74BDA46DF273}"
src="https://github.com/user-attachments/assets/9374cd2a-b7e5-46c4-a722-e141ab42f0de"
/>

---------

Co-authored-by: Connor Yoh <[email protected]>
This commit is contained in:
ConnorYoh
2025-10-06 11:29:38 +00:00
committed by GitHub
co-authored by Connor Yoh
parent be7e79be55
commit ab6edd3196
17 changed files with 661 additions and 104 deletions
@@ -1,5 +1,6 @@
import React, { createContext, useContext, useState, useRef, useCallback, useEffect, useMemo } from 'react';
import { fileStorage } from '../services/fileStorage';
import { zipFileService } from '../services/zipFileService';
import { StirlingFileStub } from '../types/fileContext';
import { downloadFiles } from '../utils/downloadUtils';
import { FileId } from '../types/file';
@@ -36,6 +37,7 @@ interface FileManagerContextValue {
onDownloadSingle: (file: StirlingFileStub) => void;
onToggleExpansion: (fileId: FileId) => void;
onAddToRecents: (file: StirlingFileStub) => void;
onUnzipFile: (file: StirlingFileStub) => Promise<void>;
onNewFilesSelect: (files: File[]) => void;
// External props
@@ -544,6 +546,30 @@ export const FileManagerProvider: React.FC<FileManagerProviderProps> = ({
}
}, [refreshRecentFiles]);
const handleUnzipFile = useCallback(async (file: StirlingFileStub) => {
try {
// Load the full file from storage
const stirlingFile = await fileStorage.getStirlingFile(file.id);
if (!stirlingFile) {
return;
}
// Extract and store files using shared service method
const result = await zipFileService.extractAndStoreFilesWithHistory(stirlingFile, file);
if (result.success) {
// Refresh file manager to show new files
await refreshRecentFiles();
}
if (result.errors.length > 0) {
console.error('Errors during unzip:', result.errors);
}
} catch (error) {
console.error('Failed to unzip file:', error);
}
}, [refreshRecentFiles]);
// Cleanup blob URLs when component unmounts
useEffect(() => {
return () => {
@@ -595,6 +621,7 @@ export const FileManagerProvider: React.FC<FileManagerProviderProps> = ({
onDownloadSingle: handleDownloadSingle,
onToggleExpansion: handleToggleExpansion,
onAddToRecents: handleAddToRecents,
onUnzipFile: handleUnzipFile,
onNewFilesSelect,
// External props
@@ -627,6 +654,7 @@ export const FileManagerProvider: React.FC<FileManagerProviderProps> = ({
handleDownloadSelected,
handleToggleExpansion,
handleAddToRecents,
handleUnzipFile,
onNewFilesSelect,
recentFiles,
isFileSupported,
@@ -0,0 +1,73 @@
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { preferencesService, UserPreferences, DEFAULT_PREFERENCES } from '../services/preferencesService';
interface PreferencesContextValue {
preferences: UserPreferences;
updatePreference: <K extends keyof UserPreferences>(
key: K,
value: UserPreferences[K]
) => Promise<void>;
resetPreferences: () => Promise<void>;
isLoading: boolean;
}
const PreferencesContext = createContext<PreferencesContextValue | undefined>(undefined);
export const PreferencesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [preferences, setPreferences] = useState<UserPreferences>(DEFAULT_PREFERENCES);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const loadPreferences = async () => {
try {
await preferencesService.initialize();
const loadedPreferences = await preferencesService.getAllPreferences();
setPreferences(loadedPreferences);
} catch (error) {
console.error('Failed to load preferences:', error);
// Keep default preferences on error
} finally {
setIsLoading(false);
}
};
loadPreferences();
}, []);
const updatePreference = useCallback(
async <K extends keyof UserPreferences>(key: K, value: UserPreferences[K]) => {
await preferencesService.setPreference(key, value);
setPreferences((prev) => ({
...prev,
[key]: value,
}));
},
[]
);
const resetPreferences = useCallback(async () => {
await preferencesService.clearAllPreferences();
setPreferences(DEFAULT_PREFERENCES);
}, []);
return (
<PreferencesContext.Provider
value={{
preferences,
updatePreference,
resetPreferences,
isLoading,
}}
>
{children}
</PreferencesContext.Provider>
);
};
export const usePreferences = (): PreferencesContextValue => {
const context = useContext(PreferencesContext);
if (!context) {
throw new Error('usePreferences must be used within a PreferencesProvider');
}
return context;
};