up and download data

This commit is contained in:
2026-01-16 15:24:37 +01:00
parent 49886655fd
commit dbc1252744
10 changed files with 271 additions and 7 deletions

View File

@@ -1,17 +1,126 @@
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'dart:convert';
import '../helpers/filament_repository.dart';
import '../pages/list_view.dart'; import '../pages/list_view.dart';
import '../helpers/web_download_helper_stub.dart'
if (dart.library.html) '../helpers/web_download_helper.dart';
class HomeController extends GetxController { class HomeController extends GetxController {
void loadFilaments() { void loadFilaments() {
// Navigiere zur Listenseite // Navigiere zur Listenseite
Get.toNamed(ListPage.namedRoute); Get.toNamed(ListPage.namedRoute);
} }
void downloadFilaments() {
// JSON Backup file herunterladen Future<void> downloadFilaments() async {
try {
// JSON-Daten vom Repository holen
final jsonData = FilamentRepository.to.exportToJson();
if (kIsWeb) {
// Web: Download direkt im Browser
final fileName =
'filament_backup_${DateTime.now().millisecondsSinceEpoch}.json';
downloadJsonFileWeb(jsonData, fileName);
} else {
// Mobile/Desktop: Datei speichern und teilen
await _downloadForMobile(jsonData);
}
Get.snackbar(
'Erfolg',
'Backup wurde erstellt',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Get.theme.colorScheme.primary.withAlpha(26),
colorText: Get.theme.colorScheme.primary,
duration: Duration(seconds: 3),
);
} catch (e) {
Get.snackbar(
'Fehler',
'Backup konnte nicht erstellt werden: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Get.theme.colorScheme.error.withAlpha(26),
colorText: Get.theme.colorScheme.error,
);
}
} }
void restoreFilaments() { Future<void> _downloadForMobile(String jsonData) async {
// JSON Backup file wiederherstellen // Temporäre Datei erstellen
final directory = await getTemporaryDirectory();
final fileName =
'filament_backup_${DateTime.now().millisecondsSinceEpoch}.json';
final file = File('${directory.path}/$fileName');
await file.writeAsString(jsonData);
// Datei über Share-Dialog teilen
await Share.shareXFiles([XFile(file.path)], text: 'Filament Backup');
}
Future<void> restoreFilaments() async {
try {
// Datei auswählen
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['json'],
);
if (result != null) {
String? jsonData;
if (kIsWeb) {
// Web: Bytes direkt lesen
final bytes = result.files.first.bytes;
if (bytes != null) {
jsonData = utf8.decode(bytes);
}
} else {
// Mobile/Desktop: Datei von Pfad lesen
final path = result.files.first.path;
if (path != null) {
final file = File(path);
jsonData = await file.readAsString();
}
}
if (jsonData != null) {
// Daten importieren
final success = await FilamentRepository.to.importFromJson(jsonData);
if (success) {
Get.snackbar(
'Erfolg',
'Backup wurde erfolgreich wiederhergestellt',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Get.theme.colorScheme.primary.withAlpha(26),
colorText: Get.theme.colorScheme.primary,
duration: Duration(seconds: 3),
);
} else {
Get.snackbar(
'Fehler',
'Ungültige Backup-Datei',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Get.theme.colorScheme.error.withAlpha(26),
colorText: Get.theme.colorScheme.error,
);
}
}
}
} catch (e) {
Get.snackbar(
'Fehler',
'Wiederherstellung fehlgeschlagen: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Get.theme.colorScheme.error.withAlpha(26),
colorText: Get.theme.colorScheme.error,
);
}
} }
} }

View File

@@ -0,0 +1,15 @@
import 'dart:convert';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
void downloadJsonFileWeb(String jsonData, String fileName) {
final bytes = utf8.encode(jsonData);
final blob = html.Blob([bytes]);
final url = html.Url.createObjectUrlFromBlob(blob);
final anchor = html.AnchorElement(href: url)
..setAttribute('download', fileName)
..click();
html.Url.revokeObjectUrl(url);
}

View File

@@ -0,0 +1,3 @@
void downloadJsonFileWeb(String jsonData, String fileName) {
throw UnsupportedError('Web download is only supported on web platform');
}

View File

@@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View File

@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@@ -5,8 +5,12 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import file_picker
import path_provider_foundation import path_provider_foundation
import share_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
} }

View File

@@ -73,6 +73,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.19.1" version: "1.19.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608"
url: "https://pub.dev"
source: hosted
version: "0.3.5+1"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@@ -105,6 +113,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.1.5"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.1"
file_picker:
dependency: "direct main"
description:
name: file_picker
sha256: ab13ae8ef5580a411c458d6207b6774a6c237d77ac37011b13994879f68a8810
url: "https://pub.dev"
source: hosted
version: "8.3.7"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev"
source: hosted
version: "1.1.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@@ -126,11 +158,24 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.0" version: "6.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1
url: "https://pub.dev"
source: hosted
version: "2.0.33"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
get: get:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -227,6 +272,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.0" version: "1.17.0"
mime:
dependency: transitive
description:
name: mime
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@@ -236,7 +289,7 @@ packages:
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
path_provider: path_provider:
dependency: transitive dependency: "direct main"
description: description:
name: path_provider name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
@@ -315,6 +368,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.3" version: "6.0.3"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: fce43200aa03ea87b91ce4c3ac79f0cecd52e2a7a56c7a4185023c271fbfa6da
url: "https://pub.dev"
source: hosted
version: "10.1.4"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
url: "https://pub.dev"
source: hosted
version: "5.0.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@@ -376,6 +445,46 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
url: "https://pub.dev"
source: hosted
version: "3.2.2"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
url: "https://pub.dev"
source: hosted
version: "2.4.2"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
uuid:
dependency: transitive
description:
name: uuid
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
url: "https://pub.dev"
source: hosted
version: "4.5.2"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@@ -400,6 +509,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
win32:
dependency: transitive
description:
name: win32
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
version: "5.15.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
@@ -426,4 +543,4 @@ packages:
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.10.4 <4.0.0" dart: ">=3.10.4 <4.0.0"
flutter: ">=3.35.0" flutter: ">=3.38.0"

View File

@@ -16,6 +16,9 @@ dependencies:
get: ^4.7.3 get: ^4.7.3
get_storage: ^2.1.1 get_storage: ^2.1.1
intl: ^0.20.2 intl: ^0.20.2
file_picker: ^8.1.6
path_provider: ^2.1.5
share_plus: ^10.1.4
dev_dependencies: dev_dependencies:
flutter_lints: ^6.0.0 flutter_lints: ^6.0.0

View File

@@ -6,6 +6,12 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@@ -3,6 +3,8 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
share_plus
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST