feat(profile): add data storage settings screen with cache management
Some checks failed
Frontend CI / build-and-push-web (push) Successful in 15m38s
Frontend CI / ota-android (push) Successful in 16m54s
Frontend CI / build-android-apk (push) Failing after 8m29s

Add DataStorageScreen for managing media cache and storage:
- Display cache statistics (image/video/audio counts and sizes)
- Show AsyncStorage usage information
- Add clear all cache functionality
- Add cleanup expired cache option (7 days threshold)
- Add storage usage breakdown by category
- Add "Last cleaned" timestamp display

Also fix MediaCacheManager to skip native cache operations on web platform:
- Return original URI directly on web without caching
- Skip directory creation on web
- Skip file existence checks on web
- Skip startup and periodic cleanup on web
This commit is contained in:
lafay
2026-04-07 16:27:02 +08:00
parent 445c1c5561
commit 25194313ae
7 changed files with 494 additions and 7 deletions

View File

@@ -6,6 +6,7 @@
import { File, Paths } from 'expo-file-system';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Platform } from 'react-native';
import {
MediaType,
CleanupTrigger,
@@ -102,13 +103,15 @@ export class MediaCacheManager {
// 加载缓存记录
await this.loadCacheRecords();
// 启动时清理
if (this.policy.cleanupOnStart) {
// 启动时清理 (非web平台)
if (this.policy.cleanupOnStart && Platform.OS !== 'web') {
await this.cleanup(CleanupTrigger.STARTUP);
}
// 启动定期清理
this.startPeriodicCleanup();
// 启动定期清理 (非web平台)
if (Platform.OS !== 'web') {
this.startPeriodicCleanup();
}
this.isInitialized = true;
} catch (error) {
@@ -121,6 +124,8 @@ export class MediaCacheManager {
* 确保缓存目录存在
*/
private async ensureDirectories(): Promise<void> {
if (Platform.OS === 'web') return;
try {
const dirs = [getImageDir(), getVideoDir(), getAudioDir()];
for (const dir of dirs) {
@@ -168,6 +173,8 @@ export class MediaCacheManager {
* 检查文件是否存在
*/
private async checkFileExists(path: string): Promise<boolean> {
if (Platform.OS === 'web') return false;
try {
const file = new File(path);
return await file.exists;
@@ -199,6 +206,10 @@ export class MediaCacheManager {
size?: number;
} = {}
): Promise<string> {
if (Platform.OS === 'web') {
return uri;
}
const { conversationId, messageId, size = 0 } = options;
// 生成唯一键