119 lines
3.5 KiB
Dart
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');
|
|
}
|
|
}
|
|
}
|