♻️ Implement delete (recreate) local database
This commit is contained in:
parent
40b885b27b
commit
ad66c11593
@ -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",
|
||||
|
@ -374,7 +374,8 @@
|
||||
"callStatusReconnected": "重连中",
|
||||
"messageOutOfSync": "消息可能与服务器脱节",
|
||||
"messageOutOfSyncCaption": "由于 App 进入后台,消息列表可能与服务器存在时差,点击刷新。",
|
||||
"messageHistoryWipe": "清除消息记录",
|
||||
"localDatabaseWipe": "清除本地数据库",
|
||||
"localDatabaseSize": "本地数据库大小:@size",
|
||||
"unknown": "未知",
|
||||
"collapse": "折叠",
|
||||
"expand": "展开",
|
||||
|
@ -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]}';
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -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),
|
||||
),
|
||||
],
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -1366,7 +1366,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
path_provider:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user