From 533d38042e8a3c73e47397b58eca081fa282cf82 Mon Sep 17 00:00:00 2001 From: dan63047 Date: Fri, 20 Oct 2023 00:45:07 +0300 Subject: [PATCH] DB compressing + prepairing for custmization --- lib/main.dart | 3 +- lib/services/sqlite_db_controller.dart | 18 +++++++ lib/utils/filesizes_converter.dart | 13 +++++ lib/views/customization_view.dart | 70 ++++++++++++++++++++++++++ lib/views/settings_view.dart | 5 ++ lib/views/tracked_players_view.dart | 17 +++++-- pubspec.lock | 8 +++ pubspec.yaml | 1 + 8 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 lib/utils/filesizes_converter.dart create mode 100644 lib/views/customization_view.dart diff --git a/lib/main.dart b/lib/main.dart index 3da5d38..80e1a86 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:tetra_stats/views/customization_view.dart'; import 'package:window_manager/window_manager.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; @@ -58,7 +59,7 @@ class MyApp extends StatelessWidget { locale: TranslationProvider.of(context).flutterLocale, supportedLocales: AppLocaleUtils.supportedLocales, localizationsDelegates: GlobalMaterialLocalizations.delegates, - routes: {"/settings": (context) => const SettingsView(), "/states": (context) => const TrackedPlayersView(), "/calc": (context) => const CalcView()}, + routes: {"/settings": (context) => const SettingsView(), "/states": (context) => const TrackedPlayersView(), "/calc": (context) => const CalcView(), "/customization": (context) => const CustomizationView()}, theme: ThemeData( fontFamily: 'Eurostile Round', colorScheme: const ColorScheme.dark(primary: Colors.cyanAccent, secondary: Colors.white), diff --git a/lib/services/sqlite_db_controller.dart b/lib/services/sqlite_db_controller.dart index f700819..0d475b2 100644 --- a/lib/services/sqlite_db_controller.dart +++ b/lib/services/sqlite_db_controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path_provider/path_provider.dart' show MissingPlatformDirectoryException, getApplicationDocumentsDirectory; @@ -58,4 +59,21 @@ class DB { // empty } } + + Future compressDB() async{ + await ensureDbIsOpen(); + final db = getDatabaseOrThrow(); + String dbPath; + if (kIsWeb) { + dbPath = dbName; + } else { + final docsPath = await getApplicationDocumentsDirectory(); + dbPath = join(docsPath.path, dbName); + } + var dbFile = File(dbPath); + var dbStats = await dbFile.stat(); + await db.execute("VACUUM"); + var newDBStats = await dbFile.stat(); + return dbStats.size - newDBStats.size; + } } diff --git a/lib/utils/filesizes_converter.dart b/lib/utils/filesizes_converter.dart new file mode 100644 index 0000000..85daa29 --- /dev/null +++ b/lib/utils/filesizes_converter.dart @@ -0,0 +1,13 @@ +import 'dart:math'; +import 'package:intl/intl.dart'; + +String bytesToSize(int num){ + if (num.toString().length<= 4) return "$num B"; + List postfixs = ["K", "M", "G", "T", "P", "E"]; + int nl = num.toString().length-1; + int scale = min((nl / 3).truncate(), postfixs.length); + double newNum = num / pow(1024, scale); + int decimalLength = nl / 3 <= postfixs.length ? 2 - nl % 3 : 0; + return "${NumberFormat.decimalPatternDigits(decimalDigits: decimalLength).format(newNum)} ${postfixs[scale-1]}iB"; +} + \ No newline at end of file diff --git a/lib/views/customization_view.dart b/lib/views/customization_view.dart new file mode 100644 index 0000000..a27ae90 --- /dev/null +++ b/lib/views/customization_view.dart @@ -0,0 +1,70 @@ +import 'dart:io'; +import 'package:tetra_stats/main.dart' show packageInfo; +import 'package:file_selector/file_selector.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:tetra_stats/gen/strings.g.dart'; +import 'package:tetra_stats/services/crud_exceptions.dart'; +import 'package:tetra_stats/services/tetrio_crud.dart'; +import 'package:tetra_stats/utils/open_in_browser.dart'; +import 'package:window_manager/window_manager.dart'; + +late String oldWindowTitle; + +class CustomizationView extends StatefulWidget { + const CustomizationView({Key? key}) : super(key: key); + + @override + State createState() => CustomizationState(); +} + +class CustomizationState extends State { + late SharedPreferences prefs; + + @override + void initState() { + if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS){ + windowManager.getTitle().then((value) => oldWindowTitle = value); + windowManager.setTitle("Tetra Stats: ${t.settings}"); + } + _getPreferences(); + super.initState(); + } + + @override + void dispose(){ + if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) windowManager.setTitle(oldWindowTitle); + super.dispose(); + } + + Future _getPreferences() async { + prefs = await SharedPreferences.getInstance(); + } + + @override + Widget build(BuildContext context) { + final t = Translations.of(context); + List>? locales = >[]; + for (var v in AppLocale.values){ + locales.add(DropdownMenuItem( + value: v, child: Text(t.locales[v.languageTag]!))); + } + return Scaffold( + appBar: AppBar( + title: Text(t.settings), + ), + backgroundColor: Colors.black, + body: SafeArea( + child: ListView( + children: [ + ListTile(title: Text("Accent Color"),), + ListTile(title: Text("Font"),), + ListTile(title: Text("Stats Table in TL mathes list"),), + ], + )), + ); + } +} diff --git a/lib/views/settings_view.dart b/lib/views/settings_view.dart index 14842d0..01bfe68 100644 --- a/lib/views/settings_view.dart +++ b/lib/views/settings_view.dart @@ -236,6 +236,11 @@ class SettingsState extends State { }, ), ), + ListTile(title: Text("Customization"), + trailing: Icon(Icons.arrow_right), + onTap: () { + Navigator.pushNamed(context, "/customization"); + },), const Divider(), ListTile( onTap: (){ diff --git a/lib/views/tracked_players_view.dart b/lib/views/tracked_players_view.dart index 0f967c0..cda5fa8 100644 --- a/lib/views/tracked_players_view.dart +++ b/lib/views/tracked_players_view.dart @@ -5,6 +5,7 @@ import 'package:intl/intl.dart'; import 'package:tetra_stats/data_objects/tetrio.dart'; import 'package:tetra_stats/gen/strings.g.dart'; import 'package:tetra_stats/services/tetrio_crud.dart'; +import 'package:tetra_stats/utils/filesizes_converter.dart'; import 'package:tetra_stats/views/states_view.dart'; import 'package:window_manager/window_manager.dart'; @@ -49,11 +50,21 @@ class TrackedPlayersState extends State { value: 1, child: Text("Remove duplicated TL mathces"), ), + PopupMenuItem( + value: 2, + child: Text("Compress DB"), + ), ], onSelected: (value) { - if (value == 1) {teto.removeDuplicatesFromTLMatches(); - return;} - Navigator.pushNamed(context, value); + switch (value) { + case 1: + teto.removeDuplicatesFromTLMatches(); + break; + case 2: + teto.compressDB().then((value) => ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Space saved: ${bytesToSize(value)}")))); + break; + default: + } }) ], ), diff --git a/pubspec.lock b/pubspec.lock index 0e451f2..bc44a03 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -270,6 +270,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_colorpicker: + dependency: "direct main" + description: + name: flutter_colorpicker + sha256: "458a6ed8ea480eb16ff892aedb4b7092b2804affd7e046591fb03127e8d8ef8b" + url: "https://pub.dev" + source: hosted + version: "1.0.3" flutter_launcher_icons: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index 5afa7df..1b728df 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: flutter_svg: any window_manager: ^0.3.7 flutter_markdown: ^0.6.18 + flutter_colorpicker: ^1.0.3 dev_dependencies: flutter_test: