♻️ Implement delete (recreate) local database

This commit is contained in:
LittleSheep 2024-09-15 12:25:50 +08:00
parent 40b885b27b
commit ad66c11593
11 changed files with 85 additions and 76 deletions

View File

@ -373,7 +373,8 @@
"callStatusReconnected": "Reconnecting",
"messageOutOfSync": "May Out of Sync with Server",
"messageOutOfSyncCaption": "Since the App has entered the background, there may be a time difference between the message list and the server. Click to Refresh.",
"messageHistoryWipe": "Wipe local message history",
"localDatabaseWipe": "Wipe local database",
"localDatabaseSize": "Overall database size: @size",
"unknown": "Unknown",
"collapse": "Collapse",
"expand": "Expand",

View File

@ -374,7 +374,8 @@
"callStatusReconnected": "重连中",
"messageOutOfSync": "消息可能与服务器脱节",
"messageOutOfSyncCaption": "由于 App 进入后台,消息列表可能与服务器存在时差,点击刷新。",
"messageHistoryWipe": "清除消息记录",
"localDatabaseWipe": "清除本地数据库",
"localDatabaseSize": "本地数据库大小:@size",
"unknown": "未知",
"collapse": "折叠",
"expand": "展开",

View File

@ -1,9 +1,11 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/exceptions/request.dart';
import 'package:solian/exceptions/unauthorized.dart';
extension SolianExtenions on BuildContext {
extension AppExtensions on BuildContext {
void showSnackbar(String content, {SnackBarAction? action}) {
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
content: Text(content),
@ -102,3 +104,24 @@ extension SolianExtenions on BuildContext {
);
}
}
extension ByteFormatter on int {
String formatBytes({int decimals = 2}) {
if (this == 0) return '0 Bytes';
const k = 1024;
final dm = decimals < 0 ? 0 : decimals;
final sizes = [
'Bytes',
'KiB',
'MiB',
'GiB',
'TiB',
'PiB',
'EiB',
'ZiB',
'YiB'
];
final i = (math.log(this) / math.log(k)).floor().toInt();
return '${(this / math.pow(k, i)).toStringAsFixed(dm)} ${sizes[i]}';
}
}

View File

@ -8,6 +8,7 @@ import 'package:get/get.dart';
import 'package:get/get_connect/http/src/request/request.dart';
import 'package:solian/exceptions/request.dart';
import 'package:solian/exceptions/unauthorized.dart';
import 'package:solian/providers/database/database.dart';
import 'package:solian/providers/websocket.dart';
import 'package:solian/services.dart';
@ -198,6 +199,8 @@ class AuthProvider extends GetConnect {
Get.find<WebSocketProvider>().notifications.clear();
Get.find<WebSocketProvider>().notificationUnread.value = 0;
AppDatabase.removeDatabase();
storage.deleteAll();
}

View File

@ -1,6 +1,11 @@
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:get/get.dart' hide Value;
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:solian/platform.dart';
import 'package:solian/providers/database/tables/messages.dart';
import 'package:solian/models/event.dart';
@ -17,8 +22,24 @@ class AppDatabase extends _$AppDatabase {
static QueryExecutor _openConnection() {
return driftDatabase(name: 'solar_network_local_db');
}
static Future<int> getDatabaseSize() async {
if (PlatformInfo.isWeb) return 0;
final basepath = await getApplicationDocumentsDirectory();
return await File(join(basepath.path, 'solar_network_local_db.sqlite'))
.length();
}
static Future<void> removeDatabase() async {
if (PlatformInfo.isWeb) return;
final basepath = await getApplicationDocumentsDirectory();
final file = File(join(basepath.path, 'solar_network_local_db.sqlite'));
await Get.find<DatabaseProvider>().database.close();
await file.delete();
Get.find<DatabaseProvider>().database = AppDatabase();
}
}
class DatabaseProvider extends GetxController {
final database = AppDatabase();
var database = AppDatabase();
}

View File

@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:solian/exts.dart';
import 'package:solian/providers/database/database.dart';
import 'package:solian/providers/theme_switcher.dart';
import 'package:solian/router.dart';
import 'package:solian/theme.dart';
@ -81,6 +82,30 @@ class _SettingScreenState extends State<SettingScreen> {
).paddingSymmetric(horizontal: 12, vertical: 8),
),
_buildCaptionHeader('more'.tr),
ListTile(
leading: const Icon(Icons.delete_sweep),
trailing: const Icon(Icons.chevron_right),
subtitle: FutureBuilder(
future: AppDatabase.getDatabaseSize(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text('localDatabaseSize'.trParams(
{'size': 'unknown'.tr},
));
}
return Text('localDatabaseSize'.trParams(
{'size': snapshot.data!.formatBytes()},
));
},
),
contentPadding: const EdgeInsets.symmetric(horizontal: 22),
title: Text('localDatabaseWipe'.tr),
onTap: () {
AppDatabase.removeDatabase().then((_) {
setState(() {});
});
},
),
ListTile(
leading: const Icon(Icons.info_outline),
trailing: const Icon(Icons.chevron_right),
@ -90,15 +115,6 @@ class _SettingScreenState extends State<SettingScreen> {
AppRouter.instance.pushNamed('about');
},
),
ListTile(
leading: const Icon(Icons.delete_sweep),
trailing: const Icon(Icons.chevron_right),
contentPadding: const EdgeInsets.symmetric(horizontal: 22),
title: Text('messageHistoryWipe'.tr),
onTap: () {
// TODO Wipe message history
},
),
],
),
);

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'dart:math' as math;
import 'package:desktop_drop/desktop_drop.dart';
import 'package:dismissible_page/dismissible_page.dart';
@ -209,25 +208,6 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
});
}
String _formatBytes(int bytes, {int decimals = 2}) {
if (bytes == 0) return '0 Bytes';
const k = 1024;
final dm = decimals < 0 ? 0 : decimals;
final sizes = [
'Bytes',
'KiB',
'MiB',
'GiB',
'TiB',
'PiB',
'EiB',
'ZiB',
'YiB'
];
final i = (math.log(bytes) / math.log(k)).floor().toInt();
return '${(bytes / math.pow(k, i)).toStringAsFixed(dm)} ${sizes[i]}';
}
void _revertMetadataList() {
final AttachmentProvider attach = Get.find();
@ -367,7 +347,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
return const SizedBox.shrink();
}
return Text(
_formatBytes(snapshot.data!),
snapshot.data!.formatBytes(),
style: Theme.of(context).textTheme.bodySmall,
);
},
@ -502,7 +482,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
),
),
Text(
'${fileType[0].toUpperCase()}${fileType.substring(1)} · ${_formatBytes(element.size)}',
'${fileType[0].toUpperCase()}${fileType.substring(1)} · ${element.size.formatBytes()}',
style: const TextStyle(fontSize: 12),
),
],

View File

@ -38,25 +38,6 @@ class _AttachmentFullScreenState extends State<AttachmentFullScreen> {
Color get _unFocusColor =>
Theme.of(context).colorScheme.onSurface.withOpacity(0.75);
String _formatBytes(int bytes, {int decimals = 2}) {
if (bytes == 0) return '0 Bytes';
const k = 1024;
final dm = decimals < 0 ? 0 : decimals;
final sizes = [
'Bytes',
'KiB',
'MiB',
'GiB',
'TiB',
'PiB',
'EiB',
'ZiB',
'YiB'
];
final i = (math.log(bytes) / math.log(k)).floor().toInt();
return '${(bytes / math.pow(k, i)).toStringAsFixed(dm)} ${sizes[i]}';
}
double _getRatio() {
final value = widget.item.metadata?['ratio'];
if (value == null) return 1;
@ -274,7 +255,7 @@ class _AttachmentFullScreenState extends State<AttachmentFullScreen> {
style: metaTextStyle,
),
Text(
_formatBytes(widget.item.size),
widget.item.size.formatBytes(),
style: metaTextStyle,
),
Text(

View File

@ -7,6 +7,7 @@ import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:solian/exts.dart';
import 'package:solian/models/attachment.dart';
import 'package:solian/providers/durations.dart';
import 'package:solian/services.dart';
@ -377,25 +378,6 @@ class _AttachmentItemAudioState extends State<_AttachmentItemAudio> {
);
}
String _formatBytes(int bytes, {int decimals = 2}) {
if (bytes == 0) return '0 Bytes';
const k = 1024;
final dm = decimals < 0 ? 0 : decimals;
final sizes = [
'Bytes',
'KiB',
'MiB',
'GiB',
'TiB',
'PiB',
'EiB',
'ZiB',
'YiB'
];
final i = (math.log(bytes) / math.log(k)).floor().toInt();
return '${(bytes / math.pow(k, i)).toStringAsFixed(dm)} ${sizes[i]}';
}
@override
void initState() {
super.initState();
@ -471,7 +453,7 @@ class _AttachmentItemAudioState extends State<_AttachmentItemAudio> {
),
),
Text(
_formatBytes(widget.item.size),
widget.item.size.formatBytes(),
style: GoogleFonts.robotoMono(
fontSize: 12,
shadows: labelShadows,

View File

@ -1366,7 +1366,7 @@ packages:
source: hosted
version: "1.0.1"
path_provider:
dependency: transitive
dependency: "direct main"
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378

View File

@ -78,6 +78,7 @@ dependencies:
drift: ^2.20.2
drift_flutter: ^0.2.0
very_good_infinite_list: ^0.8.0
path_provider: ^2.1.4
dev_dependencies:
flutter_test: