Release 1.2.0: Remove backup encryption and switch to JSON-only backups with history support
This commit is contained in:
113
src/App.tsx
113
src/App.tsx
@@ -1,4 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { Settings as SettingsIcon } from "lucide-react";
|
||||
import Settings, { SmtpConfig, AzureConfig } from "./components/Settings";
|
||||
import Recorder from "./components/Recorder";
|
||||
@@ -60,6 +61,11 @@ function App() {
|
||||
return localStorage.getItem('hearbit_selected_model') || 'mixtral';
|
||||
});
|
||||
|
||||
// Daily Backup State
|
||||
const [dailyBackupEnabled, setDailyBackupEnabled] = useState(() => localStorage.getItem('hearbit_daily_backup_enabled') === 'true');
|
||||
const [dailyBackupPath, setDailyBackupPath] = useState(() => localStorage.getItem('hearbit_daily_backup_path') || '');
|
||||
const [lastBackupDate, setLastBackupDate] = useState(() => localStorage.getItem('hearbit_last_backup_date') || '');
|
||||
|
||||
const handleModelChange = (model: string) => {
|
||||
setSelectedModel(model);
|
||||
localStorage.setItem('hearbit_selected_model', model);
|
||||
@@ -227,6 +233,7 @@ Thanks!`
|
||||
return saved ? JSON.parse(saved) : defaultEmailTemplates;
|
||||
});
|
||||
|
||||
|
||||
const handleSaveSettings = (
|
||||
newApiKey: string,
|
||||
newProductId: string,
|
||||
@@ -234,7 +241,9 @@ Thanks!`
|
||||
newSavePath: string,
|
||||
newSmtp: SmtpConfig,
|
||||
newAzure: AzureConfig,
|
||||
newEmailTemplates: EmailTemplate[]
|
||||
newEmailTemplates: EmailTemplate[],
|
||||
newDailyBackupEnabled: boolean,
|
||||
newDailyBackupPath: string
|
||||
) => {
|
||||
setApiKey(newApiKey);
|
||||
setProductId(newProductId);
|
||||
@@ -244,14 +253,20 @@ Thanks!`
|
||||
setAzureConfig(newAzure);
|
||||
setEmailTemplates(newEmailTemplates);
|
||||
|
||||
localStorage.setItem('infomaniak_api_key', newApiKey);
|
||||
localStorage.setItem('infomaniak_product_id', newProductId);
|
||||
localStorage.setItem('infomaniak_prompts', JSON.stringify(newPrompts));
|
||||
localStorage.setItem('infomaniak_save_path', newSavePath);
|
||||
setDailyBackupEnabled(newDailyBackupEnabled);
|
||||
setDailyBackupPath(newDailyBackupPath);
|
||||
|
||||
localStorage.setItem('hearbit_api_key', newApiKey);
|
||||
localStorage.setItem('hearbit_product_id', newProductId);
|
||||
localStorage.setItem('hearbit_prompts', JSON.stringify(newPrompts));
|
||||
localStorage.setItem('hearbit_save_path', newSavePath);
|
||||
localStorage.setItem('hearbit_smtp_config', JSON.stringify(newSmtp));
|
||||
localStorage.setItem('hearbit_azure_config', JSON.stringify(newAzure));
|
||||
localStorage.setItem('hearbit_email_templates', JSON.stringify(newEmailTemplates));
|
||||
|
||||
localStorage.setItem('hearbit_daily_backup_enabled', String(newDailyBackupEnabled));
|
||||
localStorage.setItem('hearbit_daily_backup_path', newDailyBackupPath);
|
||||
|
||||
setView(lastTab);
|
||||
};
|
||||
|
||||
@@ -332,6 +347,80 @@ Thanks!`
|
||||
setView('transcription'); // Switch to Transcription view to see content
|
||||
};
|
||||
|
||||
const performBackup = useCallback(async (isAuto = false) => {
|
||||
try {
|
||||
if (isAuto && !dailyBackupEnabled) return;
|
||||
|
||||
const dataToBackup = {
|
||||
apiKey,
|
||||
productId,
|
||||
prompts,
|
||||
savePath,
|
||||
smtp: smtpConfig,
|
||||
azure: azureConfig,
|
||||
emailTemplates,
|
||||
history, // Including history!
|
||||
// Also include daily backup settings so they persist on restore
|
||||
dailyBackup: {
|
||||
enabled: dailyBackupEnabled,
|
||||
path: dailyBackupPath,
|
||||
}
|
||||
};
|
||||
|
||||
// Always save as JSON (no encryption)
|
||||
const content = JSON.stringify(dataToBackup, null, 2);
|
||||
|
||||
const dateStr = new Date().toISOString().slice(0, 10);
|
||||
const fileName = `hearbit_backup_${isAuto ? 'auto_' : ''}${dateStr}.json`;
|
||||
|
||||
// Determine path: use specific daily backup path, or general savePath
|
||||
const targetDir = (isAuto ? dailyBackupPath : savePath) || savePath;
|
||||
|
||||
if (!targetDir) {
|
||||
if (!isAuto) addToast('No backup path configured.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const fullPath = `${targetDir}/${fileName}`;
|
||||
|
||||
await invoke('save_text_file', { path: fullPath, content });
|
||||
|
||||
if (isAuto) {
|
||||
const now = new Date().toISOString();
|
||||
setLastBackupDate(now);
|
||||
localStorage.setItem('hearbit_last_backup_date', now);
|
||||
console.log("Auto-backup completed:", fullPath);
|
||||
} else {
|
||||
addToast(`Backup saved to ${fullPath}`, 'success');
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error("Backup failed:", e);
|
||||
if (!isAuto) addToast(`Backup failed: ${e}`, 'error');
|
||||
}
|
||||
}, [apiKey, productId, prompts, savePath, smtpConfig, azureConfig, emailTemplates, history, dailyBackupEnabled, dailyBackupPath]);
|
||||
|
||||
// Check for Daily Backup on Mount / State Change
|
||||
useEffect(() => {
|
||||
if (!dailyBackupEnabled) return;
|
||||
|
||||
const check = async () => {
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const last = lastBackupDate ? lastBackupDate.slice(0, 10) : '';
|
||||
|
||||
if (last !== today) {
|
||||
// Perform backup
|
||||
await performBackup(true);
|
||||
}
|
||||
};
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
check();
|
||||
}, 5000); // Check 5s after load to allow state to settle
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [dailyBackupEnabled, lastBackupDate, performBackup]);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
@@ -474,6 +563,18 @@ Thanks!`
|
||||
smtpConfig={smtpConfig}
|
||||
azureConfig={azureConfig}
|
||||
emailTemplates={emailTemplates}
|
||||
|
||||
// Pass new backup props
|
||||
dailyBackupEnabled={dailyBackupEnabled}
|
||||
dailyBackupPath={dailyBackupPath}
|
||||
lastBackupDate={lastBackupDate}
|
||||
|
||||
// Pass history and update callback
|
||||
history={history}
|
||||
onHistoryUpdate={(newHistory) => {
|
||||
setHistory(newHistory);
|
||||
localStorage.setItem('infomaniak_history', JSON.stringify(newHistory));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user