feat: enhance backup and download functionalities

- Updated `BackupCenterPage` to support download progress tracking during remote backup downloads.
- Modified `ImportPage` to simplify export functionality by removing unnecessary payload handling.
- Improved `JwtWarningPage` to utilize a new clipboard utility for copying text with feedback.
- Enhanced `PublicSendPage` to show download progress for files being downloaded.
- Updated `RecoverTwoFactorPage` to include autocomplete attributes for better user experience.
- Refactored `SendsPage` to use the new clipboard utility for copying access URLs.
- Enhanced `SettingsPage` to utilize the clipboard utility for copying sensitive information.
- Improved `TotpCodesPage` to use the clipboard utility for copying TOTP codes.
- Updated `VaultPage` and related components to support download progress for attachments.
- Introduced a new `app-notify` module for consistent notification handling across the application.
- Created a `clipboard` utility for improved clipboard interactions with user feedback.
- Added progress tracking for file downloads in the API layer, enhancing user experience during downloads.
This commit is contained in:
shuaiplus
2026-03-15 23:12:45 +08:00
parent 9820c2ed44
commit 4b8cad6d00
33 changed files with 387 additions and 121 deletions
+4 -2
View File
@@ -14,6 +14,7 @@ import {
parseJson,
type AuthedFetch,
} from './shared';
import { readResponseBytesWithProgress } from '../download';
export async function getFolders(authedFetch: AuthedFetch): Promise<Folder[]> {
const resp = await authedFetch('/api/folders');
@@ -331,7 +332,8 @@ export async function downloadCipherAttachmentDecrypted(
authedFetch: AuthedFetch,
session: SessionState,
cipher: Cipher,
attachmentId: string
attachmentId: string,
onProgress?: (percent: number | null) => void
): Promise<{ fileName: string; bytes: Uint8Array }> {
if (!session.symEncKey || !session.symMacKey) throw new Error('Vault key unavailable');
const cid = String(cipher?.id || '').trim();
@@ -341,7 +343,7 @@ export async function downloadCipherAttachmentDecrypted(
const info = await getAttachmentDownloadInfo(authedFetch, cid, aid);
const rawResp = await fetch(info.url, { cache: 'no-store' });
if (!rawResp.ok) throw new Error('Download attachment failed');
const encryptedBytes = new Uint8Array(await rawResp.arrayBuffer());
const encryptedBytes = await readResponseBytesWithProgress(rawResp, (progress) => onProgress?.(progress.percent));
const userEnc = base64ToBytes(session.symEncKey);
const userMac = base64ToBytes(session.symMacKey);