♻️ Implement delete (recreate) local database
This commit is contained in:
parent
40b885b27b
commit
ad66c11593
@ -373,7 +373,8 @@
|
|||||||
"callStatusReconnected": "Reconnecting",
|
"callStatusReconnected": "Reconnecting",
|
||||||
"messageOutOfSync": "May Out of Sync with Server",
|
"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.",
|
"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",
|
"unknown": "Unknown",
|
||||||
"collapse": "Collapse",
|
"collapse": "Collapse",
|
||||||
"expand": "Expand",
|
"expand": "Expand",
|
||||||
|
@ -374,7 +374,8 @@
|
|||||||
"callStatusReconnected": "重连中",
|
"callStatusReconnected": "重连中",
|
||||||
"messageOutOfSync": "消息可能与服务器脱节",
|
"messageOutOfSync": "消息可能与服务器脱节",
|
||||||
"messageOutOfSyncCaption": "由于 App 进入后台,消息列表可能与服务器存在时差,点击刷新。",
|
"messageOutOfSyncCaption": "由于 App 进入后台,消息列表可能与服务器存在时差,点击刷新。",
|
||||||
"messageHistoryWipe": "清除消息记录",
|
"localDatabaseWipe": "清除本地数据库",
|
||||||
|
"localDatabaseSize": "本地数据库大小:@size",
|
||||||
"unknown": "未知",
|
"unknown": "未知",
|
||||||
"collapse": "折叠",
|
"collapse": "折叠",
|
||||||
"expand": "展开",
|
"expand": "展开",
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:solian/exceptions/request.dart';
|
import 'package:solian/exceptions/request.dart';
|
||||||
import 'package:solian/exceptions/unauthorized.dart';
|
import 'package:solian/exceptions/unauthorized.dart';
|
||||||
|
|
||||||
extension SolianExtenions on BuildContext {
|
extension AppExtensions on BuildContext {
|
||||||
void showSnackbar(String content, {SnackBarAction? action}) {
|
void showSnackbar(String content, {SnackBarAction? action}) {
|
||||||
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
|
||||||
content: Text(content),
|
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:get/get_connect/http/src/request/request.dart';
|
||||||
import 'package:solian/exceptions/request.dart';
|
import 'package:solian/exceptions/request.dart';
|
||||||
import 'package:solian/exceptions/unauthorized.dart';
|
import 'package:solian/exceptions/unauthorized.dart';
|
||||||
|
import 'package:solian/providers/database/database.dart';
|
||||||
import 'package:solian/providers/websocket.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
|
|
||||||
@ -198,6 +199,8 @@ class AuthProvider extends GetConnect {
|
|||||||
Get.find<WebSocketProvider>().notifications.clear();
|
Get.find<WebSocketProvider>().notifications.clear();
|
||||||
Get.find<WebSocketProvider>().notificationUnread.value = 0;
|
Get.find<WebSocketProvider>().notificationUnread.value = 0;
|
||||||
|
|
||||||
|
AppDatabase.removeDatabase();
|
||||||
|
|
||||||
storage.deleteAll();
|
storage.deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift_flutter/drift_flutter.dart';
|
import 'package:drift_flutter/drift_flutter.dart';
|
||||||
import 'package:get/get.dart' hide Value;
|
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/providers/database/tables/messages.dart';
|
||||||
|
|
||||||
import 'package:solian/models/event.dart';
|
import 'package:solian/models/event.dart';
|
||||||
@ -17,8 +22,24 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
static QueryExecutor _openConnection() {
|
static QueryExecutor _openConnection() {
|
||||||
return driftDatabase(name: 'solar_network_local_db');
|
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 {
|
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:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
|
import 'package:solian/providers/database/database.dart';
|
||||||
import 'package:solian/providers/theme_switcher.dart';
|
import 'package:solian/providers/theme_switcher.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:solian/theme.dart';
|
import 'package:solian/theme.dart';
|
||||||
@ -81,6 +82,30 @@ class _SettingScreenState extends State<SettingScreen> {
|
|||||||
).paddingSymmetric(horizontal: 12, vertical: 8),
|
).paddingSymmetric(horizontal: 12, vertical: 8),
|
||||||
),
|
),
|
||||||
_buildCaptionHeader('more'.tr),
|
_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(
|
ListTile(
|
||||||
leading: const Icon(Icons.info_outline),
|
leading: const Icon(Icons.info_outline),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
@ -90,15 +115,6 @@ class _SettingScreenState extends State<SettingScreen> {
|
|||||||
AppRouter.instance.pushNamed('about');
|
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:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math' as math;
|
|
||||||
|
|
||||||
import 'package:desktop_drop/desktop_drop.dart';
|
import 'package:desktop_drop/desktop_drop.dart';
|
||||||
import 'package:dismissible_page/dismissible_page.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() {
|
void _revertMetadataList() {
|
||||||
final AttachmentProvider attach = Get.find();
|
final AttachmentProvider attach = Get.find();
|
||||||
|
|
||||||
@ -367,7 +347,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
|||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
return Text(
|
return Text(
|
||||||
_formatBytes(snapshot.data!),
|
snapshot.data!.formatBytes(),
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -502,7 +482,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'${fileType[0].toUpperCase()}${fileType.substring(1)} · ${_formatBytes(element.size)}',
|
'${fileType[0].toUpperCase()}${fileType.substring(1)} · ${element.size.formatBytes()}',
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -38,25 +38,6 @@ class _AttachmentFullScreenState extends State<AttachmentFullScreen> {
|
|||||||
Color get _unFocusColor =>
|
Color get _unFocusColor =>
|
||||||
Theme.of(context).colorScheme.onSurface.withOpacity(0.75);
|
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() {
|
double _getRatio() {
|
||||||
final value = widget.item.metadata?['ratio'];
|
final value = widget.item.metadata?['ratio'];
|
||||||
if (value == null) return 1;
|
if (value == null) return 1;
|
||||||
@ -274,7 +255,7 @@ class _AttachmentFullScreenState extends State<AttachmentFullScreen> {
|
|||||||
style: metaTextStyle,
|
style: metaTextStyle,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
_formatBytes(widget.item.size),
|
widget.item.size.formatBytes(),
|
||||||
style: metaTextStyle,
|
style: metaTextStyle,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
|
@ -7,6 +7,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
import 'package:media_kit_video/media_kit_video.dart';
|
import 'package:media_kit_video/media_kit_video.dart';
|
||||||
|
import 'package:solian/exts.dart';
|
||||||
import 'package:solian/models/attachment.dart';
|
import 'package:solian/models/attachment.dart';
|
||||||
import 'package:solian/providers/durations.dart';
|
import 'package:solian/providers/durations.dart';
|
||||||
import 'package:solian/services.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
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -471,7 +453,7 @@ class _AttachmentItemAudioState extends State<_AttachmentItemAudio> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
_formatBytes(widget.item.size),
|
widget.item.size.formatBytes(),
|
||||||
style: GoogleFonts.robotoMono(
|
style: GoogleFonts.robotoMono(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
shadows: labelShadows,
|
shadows: labelShadows,
|
||||||
|
@ -1366,7 +1366,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||||
|
@ -78,6 +78,7 @@ dependencies:
|
|||||||
drift: ^2.20.2
|
drift: ^2.20.2
|
||||||
drift_flutter: ^0.2.0
|
drift_flutter: ^0.2.0
|
||||||
very_good_infinite_list: ^0.8.0
|
very_good_infinite_list: ^0.8.0
|
||||||
|
path_provider: ^2.1.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user