From 3a9bc5fe7d768387c252e70fe778f01bd9403611 Mon Sep 17 00:00:00 2001 From: odweta Date: Fri, 3 Apr 2026 13:01:22 +0200 Subject: [PATCH] added quotes export to file --- frontend/lib/model/quote.dart | 5 + frontend/lib/pages/list.dart | 11 +- frontend/lib/provider/quote_provider.dart | 28 ++++ frontend/lib/values/strings.dart | 1 + frontend/pubspec.lock | 166 +++++++++++++++++++++- frontend/pubspec.yaml | 1 + 6 files changed, 203 insertions(+), 9 deletions(-) diff --git a/frontend/lib/model/quote.dart b/frontend/lib/model/quote.dart index f50c252..7473cd0 100644 --- a/frontend/lib/model/quote.dart +++ b/frontend/lib/model/quote.dart @@ -18,4 +18,9 @@ class Quote{ body: json['body'], ); } + + @override + String toString() { + return "$body - $author"; + } } \ No newline at end of file diff --git a/frontend/lib/pages/list.dart b/frontend/lib/pages/list.dart index 21e221b..407b88f 100644 --- a/frontend/lib/pages/list.dart +++ b/frontend/lib/pages/list.dart @@ -274,8 +274,15 @@ class ListPage extends StatelessWidget { title: Text(Strings.exportSelectedQuotes), trailing: Icon(Icons.import_export), onTap: () { - // TODO: trigger an os dialog FileSave - }, + provider.exportQuotesToFile(); + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(Strings.fileExportedSuccessfully), + duration: const Duration(seconds: 3), + ), + ); + } ), ], ), diff --git a/frontend/lib/provider/quote_provider.dart b/frontend/lib/provider/quote_provider.dart index 9d5894e..64fe4d6 100644 --- a/frontend/lib/provider/quote_provider.dart +++ b/frontend/lib/provider/quote_provider.dart @@ -1,10 +1,12 @@ // gets all quotes from the database and returns them in a list +import 'package:path_provider/path_provider.dart'; import 'package:flutter/material.dart'; import 'package:frontend/model/quote.dart'; import 'package:frontend/repository/quote_repository.dart'; import 'dart:math'; +import 'dart:io'; class QuoteProvider extends ChangeNotifier { List _quotes = []; @@ -149,4 +151,30 @@ class QuoteProvider extends ChangeNotifier { populateAuthors(); notifyListeners(); } + + + Future _getSaveDirectory() async { + if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { + final path = Platform.isWindows + ? Platform.environment['USERPROFILE'] + : Platform.environment['HOME']; + + return Directory(path!); + } + + // Mobile fallback + return await getApplicationDocumentsDirectory(); + } + + Future exportQuotesToFile() async { + final dir = await _getSaveDirectory(); + + final datetime = DateTime.now().toUtc().toString() + .replaceAll(" ", "T") + .replaceAll(":", "-") + .replaceAll(RegExp(r"\..*"), ""); + + final file = File('${dir.path}/hlasky_$datetime.txt'); + await file.writeAsString("${filteredQuotes.join("\n")}\n"); + } } \ No newline at end of file diff --git a/frontend/lib/values/strings.dart b/frontend/lib/values/strings.dart index 57756d0..2ee56d6 100644 --- a/frontend/lib/values/strings.dart +++ b/frontend/lib/values/strings.dart @@ -22,6 +22,7 @@ class Strings { static const String flipFlashcard = "Otočit flashkartu"; static const String nextFlashcard = "Další flashkarta"; + static const String fileExportedSuccessfully = "Soubor byl úspěšně vyexportován."; static const String noUndo = "Tuto akci nelze odčinit."; static const String filterQuery = "Filtrovací požadavek"; static const String allQuotesCount = "Celkový počet hlášek"; diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index 8c4f5b3..9b40600 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.13.1" boolean_selector: dependency: transitive description: @@ -33,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" collection: dependency: transitive description: @@ -41,14 +49,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" url: "https://pub.dev" source: hosted - version: "1.0.8" + version: "1.0.9" fake_async: dependency: transitive description: @@ -57,6 +73,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -80,14 +112,30 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" go_router: dependency: "direct main" description: name: go_router - sha256: "7974313e217a7771557add6ff2238acb63f635317c35fa590d348fb238f00896" + sha256: "48fb2f42ad057476fa4b733cb95e9f9ea7b0b010bb349ea491dca7dbdb18ffc4" url: "https://pub.dev" source: hosted - version: "17.1.0" + version: "17.2.0" + hooks: + dependency: transitive + description: + name: hooks + sha256: e79ed1e8e1929bc6ecb6ec85f0cb519c887aa5b423705ded0d0f2d9226def388 + url: "https://pub.dev" + source: hosted + version: "1.0.2" http: dependency: "direct main" description: @@ -168,6 +216,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572" + url: "https://pub.dev" + source: hosted + version: "0.17.6" nested: dependency: transitive description: @@ -176,6 +232,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + url: "https://pub.dev" + source: hosted + version: "9.3.0" path: dependency: transitive description: @@ -184,6 +248,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba" + url: "https://pub.dev" + source: hosted + version: "2.2.23" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" provider: dependency: "direct main" description: @@ -192,6 +320,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" sky_engine: dependency: transitive description: flutter @@ -277,6 +413,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" sdks: dart: ">=3.11.3 <4.0.0" - flutter: ">=3.35.0" + flutter: ">=3.38.4" diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index 924c57f..962d10f 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -37,6 +37,7 @@ dependencies: provider: go_router: http: ^1.2.0 + path_provider: dev_dependencies: flutter_test: