60 lines
1.8 KiB
Dart
60 lines
1.8 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:file_picker/file_picker.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:share_plus/share_plus.dart';
|
|
|
|
import '../async_action_button.dart';
|
|
import '../info_dialog.dart';
|
|
import '../share_position_origin.dart';
|
|
|
|
/// "Teilen"/"Speichern" for a file that is on disk, shared by the file viewer
|
|
/// and the media gallery.
|
|
Future<void> shareLocalFile(BuildContext context, String path) =>
|
|
runWithErrorDialog(
|
|
context,
|
|
() => SharePlus.instance.share(
|
|
ShareParams(
|
|
files: [XFile(path)],
|
|
sharePositionOrigin: SharePositionOrigin.get(context),
|
|
),
|
|
),
|
|
);
|
|
|
|
Future<void> saveLocalFile(BuildContext context, String path) async {
|
|
try {
|
|
final source = File(path);
|
|
final size = await source.length();
|
|
// file_picker has no path/stream save API, so the whole file
|
|
// gets loaded into RAM. Cap big media; user falls back to share.
|
|
const maxBytes = 200 * 1024 * 1024;
|
|
if (size > maxBytes) {
|
|
if (!context.mounted) return;
|
|
InfoDialog.show(
|
|
context,
|
|
'Diese Datei ist zu groß (${(size / (1024 * 1024)).toStringAsFixed(0)} MB), '
|
|
'um direkt gespeichert zu werden. Nutze stattdessen die Teilen-Funktion.',
|
|
title: 'Speichern nicht möglich',
|
|
);
|
|
return;
|
|
}
|
|
final bytes = await source.readAsBytes();
|
|
final saved = await FilePicker.saveFile(
|
|
fileName: path.split('/').last,
|
|
bytes: bytes,
|
|
);
|
|
if (!context.mounted) return;
|
|
if (saved != null) {
|
|
InfoDialog.show(context, 'Datei gespeichert.');
|
|
}
|
|
} on Object catch (e) {
|
|
if (!context.mounted) return;
|
|
InfoDialog.show(
|
|
context,
|
|
'Speichern fehlgeschlagen: $e',
|
|
copyable: true,
|
|
title: 'Fehler',
|
|
);
|
|
}
|
|
}
|