Files
PeachDeployments/lib/Peach/see/files/ViewFiles.dart
alvocool 38881d1fe1 Add app source and tests
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:15:30 +03:00

119 lines
3.5 KiB
Dart

import 'dart:io';
import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import '../../about/internal/application/ServerProfile.dart';
import '../../comms/Comms.dart' show TransferProgress;
import '../parent/ParentViewModel.dart';
import 'ConnectFiles.dart';
class ViewFiles extends ParentViewModel {
ConnectFiles connection;
ViewFiles(super.context, this.connection);
/// Upload/download progress, subscribed to by the screen so the bar can
/// track a transfer as it runs.
Stream<TransferProgress?> get transferProgress =>
getDataManager().transferProgress;
/// Resolves the login directory so the browser opens somewhere useful.
void resolveHome(ServerProfile server) async {
if (!await canReach(server, () => resolveHome(server))) return;
try {
final home = await getDataManager().resolveHome(server);
connection.onHomeResolved(home);
} catch (error) {
connection.onDirectoryFailed(error.toString());
}
}
void listDirectory(ServerProfile server, String path) async {
try {
final entries = await getDataManager().listDir(server, path);
connection.onDirectoryLoaded(entries);
} catch (error) {
connection.onDirectoryFailed(error.toString());
}
}
/// Uploads bytes already in memory (a drag-and-drop payload).
void uploadBytes(
ServerProfile server,
String remotePath,
Uint8List bytes,
String label,
) async {
if (!await canReach(
server,
() => uploadBytes(server, remotePath, bytes, label),
)) {
return;
}
try {
await getDataManager().uploadFile(server, bytes, remotePath);
connection.onTransferFinished('Uploaded $label');
} catch (error) {
connection.onTransferFinished('Upload failed: $error');
}
}
/// Prompts for a local file, then uploads it into [directory].
void uploadPicked(
ServerProfile server,
String directory,
String Function(String, String) join,
) async {
try {
final picked = await FilePicker.pickFiles(withData: true);
if (picked == null || picked.files.isEmpty) return;
final file = picked.files.first;
final bytes = file.bytes ?? await File(file.path!).readAsBytes();
uploadBytes(server, join(directory, file.name), bytes, file.name);
} catch (error) {
handleError(
error,
() => uploadPicked(server, directory, join),
() {},
"Retry",
);
}
}
/// Downloads [remotePath] and writes it wherever the user chooses.
void downloadFile(
ServerProfile server,
String remotePath,
String fileName,
) async {
if (!await canReach(
server,
() => downloadFile(server, remotePath, fileName),
)) {
return;
}
try {
final bytes = await getDataManager().downloadFile(server, remotePath);
final saved = await FilePicker.saveFile(fileName: fileName, bytes: bytes);
connection.onTransferFinished(
saved == null ? 'Download cancelled' : 'Saved to $saved',
);
} catch (error) {
connection.onTransferFinished('Download failed: $error');
}
}
void deleteEntry(ServerProfile server, String remotePath, bool isDir) async {
if (!await canReach(server, () => deleteEntry(server, remotePath, isDir))) {
return;
}
try {
await getDataManager().deleteRemote(server, remotePath, isDir);
connection.onEntryDeleted();
} catch (error) {
connection.onTransferFinished('Delete failed: $error');
}
}
}