fix media compaction and mobile menu

This commit is contained in:
ngfchl
2026-07-19 11:57:38 +08:00
parent 8b46330c46
commit fc912113f6
3 changed files with 26 additions and 49 deletions
+14 -9
View File
@@ -265,14 +265,8 @@ class MediaLibraryStore {
Future<MediaLibraryStorageStats> optimizeStorage() async {
final db = await _db;
final before = await _databaseBytes(db.path);
final columns = await _tableColumns(db, 'main', 'media_items');
final hasLegacyArtwork =
columns.contains('poster') || columns.contains('backdrop');
final removedArtwork = hasLegacyArtwork
? await db.rawUpdate('''UPDATE media_items
SET poster = NULL, backdrop = NULL
WHERE poster IS NOT NULL OR backdrop IS NOT NULL''')
: 0;
final migration = await _migrateArtworkBlobSchema(db);
final removedArtwork = migration?.rows ?? 0;
try {
await db.execute('PRAGMA wal_checkpoint(TRUNCATE)');
} on DatabaseException catch (error) {
@@ -722,7 +716,18 @@ class MediaLibraryStore {
'开始压缩刮削数据库:共 $pages 页,空闲 $free 页,当前 ${_formatBytes(before)}',
);
try {
await db.execute('PRAGMA wal_checkpoint(TRUNCATE)');
try {
await db.execute('PRAGMA wal_checkpoint(TRUNCATE)');
} on DatabaseException catch (error) {
// sqflite_darwin reports a completed checkpoint as Code=0 / "not an
// error" on some macOS and iOS versions. Continue to VACUUM.
final description = error.toString();
if (!description.contains('Code=0') ||
!description.contains('not an error')) {
rethrow;
}
AppLogger.info('Storage', '数据库日志已整理,继续压缩主数据库');
}
await db.execute('VACUUM');
final after = await _databaseBytes(db.path);
AppLogger.info(
-13
View File
@@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:io';
import 'dart:ui' show PlatformDispatcher;
import 'package:flutter/material.dart';
@@ -6,7 +5,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:window_manager/window_manager.dart';
import 'package:media_kit/media_kit.dart';
import 'core/storage/storage_manager.dart';
import 'core/storage/media_library_store.dart';
import 'core/logging/app_logger.dart';
import 'core/http/dio_client.dart';
import 'app/app.dart';
@@ -53,17 +51,6 @@ void main() async {
_triggerNetworkPermission();
runApp(const ProviderScope(child: GuangyaApp()));
// Run legacy artwork cleanup once on every launch. It shares the database
// opening future with the media library, so entering the library while this
// runs cannot start another migration.
unawaited(_initializeMediaLibraryStorage());
}
Future<void> _initializeMediaLibraryStorage() async {
AppLogger.info('Storage', '正在检查刮削数据库中的旧图片缓存');
await MediaLibraryStore().initialize();
AppLogger.info('Storage', '刮削数据库检查与压缩任务完成');
}
/// Startup network permission trigger
+12 -27
View File
@@ -1134,34 +1134,19 @@ class _MobileMenuRow extends StatelessWidget {
Widget build(BuildContext context) {
final cs = ShadTheme.of(context).colorScheme;
final color = destructive ? cs.destructive : cs.foreground;
return Semantics(
button: true,
label: label,
child: InkWell(
borderRadius: BorderRadius.circular(8),
onTap: onTap,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
child: Row(
children: [
Icon(
icon,
size: 20,
color: destructive ? cs.destructive : cs.mutedForeground,
),
const SizedBox(width: 12),
Text(
label,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: color,
),
),
],
),
),
return ShadButton.ghost(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
mainAxisAlignment: MainAxisAlignment.start,
foregroundColor: color,
textStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
leading: Icon(
icon,
size: 20,
color: destructive ? cs.destructive : cs.mutedForeground,
),
onPressed: onTap,
child: Text(label),
);
}
}