diff --git a/lib/core/storage/media_library_store.dart b/lib/core/storage/media_library_store.dart index 17abee5..581d9e6 100644 --- a/lib/core/storage/media_library_store.dart +++ b/lib/core/storage/media_library_store.dart @@ -265,14 +265,8 @@ class MediaLibraryStore { Future 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( diff --git a/lib/main.dart b/lib/main.dart index b9642ff..8a8f7c0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -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 _initializeMediaLibraryStorage() async { - AppLogger.info('Storage', '正在检查刮削数据库中的旧图片缓存'); - await MediaLibraryStore().initialize(); - AppLogger.info('Storage', '刮削数据库检查与压缩任务完成'); } /// Startup network permission trigger diff --git a/lib/pages/workspace_page.dart b/lib/pages/workspace_page.dart index bb0f98d..e4e0d6d 100644 --- a/lib/pages/workspace_page.dart +++ b/lib/pages/workspace_page.dart @@ -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), ); } }