diff --git a/lib/sftp_explorer.dart b/lib/sftp_explorer.dart index 5fd116f..d213c05 100644 --- a/lib/sftp_explorer.dart +++ b/lib/sftp_explorer.dart @@ -6,6 +6,8 @@ import 'package:file_selector/file_selector.dart'; import 'package:flutter/material.dart'; import 'package:fluxcloud/sftp_worker.dart'; +import 'widgets/operation_buttons.dart'; + class SftpExplorer extends StatefulWidget { const SftpExplorer({super.key, required this.sftpWorker}); @@ -122,108 +124,7 @@ class _SftpExplorerState extends State { return ListTile( leading: Icon(dirEntry.attr.isDirectory ? Icons.folder : Icons.description), title: Text(dirEntry.filename), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - onPressed: () { - - }, - icon: Icon(Icons.drive_file_move) - ), - IconButton( - onPressed: () { - - }, - icon: Icon(Icons.copy) - ), - IconButton( - onPressed: () { - final newNameController = TextEditingController(text: dirEntry.filename); - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text('Rename'), - content: TextField( - controller: newNameController, - autofocus: true, - decoration: InputDecoration( - labelText: 'Enter new name' - ), - ), - actions: [ - TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancel')), - TextButton( - onPressed: () async { - // try { - // await widget.sftpWorker.rename('${path}${dirEntry.filename}', '${widget.path}${newNameController.text}'); - // _listDir(); - // } - // on SftpStatusError catch (e) { - // if (context.mounted) { - // ScaffoldMessenger.of(context).showSnackBar(_buildErrorSnackBar(context, e.message)); - // } - // } - // if (context.mounted) { - // Navigator.pop(context); - // } - // - }, - child: Text('Rename') - ), - - ], - ) - ); - }, - icon: Icon(Icons.drive_file_rename_outline) - ), - IconButton( - onPressed: () { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text('Delete Permanently?'), - content: Text(dirEntry.attr.isDirectory ? 'The contents of this folder will be deleted as well\nThis action cannot be undone' : 'This action cannot be undone'), - actions: [ - TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancel')), - TextButton( - onPressed: () async { - // if (dirEntry.attr.isDirectory) { - // Future removeRecursively (String path) async { - // final dirContents = await widget.sftpWorker.listdir(path); - // for (SftpName entry in dirContents) { - // final fullPath = '$path${entry.filename}'; - // if (entry.attr.isDirectory) { - // await removeRecursively('$fullPath/'); - // await widget.sftpWorker.rmdir('$fullPath/'); - // } - // else { - // await widget.sftpWorker.remove(fullPath); - // } - // } - // await widget.sftpWorker.rmdir(path); - // } - // await removeRecursively('${path}${dirEntry.filename}/'); - // } - // else { - // await widget.sftpWorker.remove('${path}${dirEntry.filename}'); - // } - // _listDir(); - // if (context.mounted) { - // Navigator.pop(context); - // } - }, - child: Text('Yes') - ), - ], - ) - ); - }, - icon: Icon(Icons.delete) - ), - ], - ), + trailing: OperationButtons(dirEntry: dirEntry), onTap: () { if (dirEntry.attr.isDirectory) { path = '$path${dirEntry.filename}/'; diff --git a/lib/widgets/loading_overlay.dart b/lib/widgets/loading_overlay.dart deleted file mode 100644 index be57ac7..0000000 --- a/lib/widgets/loading_overlay.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:dartssh2/dartssh2.dart'; -import 'package:file_selector/file_selector.dart'; -import 'package:flutter/material.dart'; - -class LoadingOverlay extends StatefulWidget{ - const LoadingOverlay({ - super.key, required this.sftpClient, required this.path, required this.files, - }); - - final SftpClient sftpClient; - final String path; - final List files; - - @override - State createState() => _LoadingOverlayState(); -} - -class _LoadingOverlayState extends State { - - Future uploadFiles() async { - for (final file in widget.files) { - final fileSize = await file.length(); - final remoteFile = await widget.sftpClient.open( - '${widget.path}${file.name}', - mode: SftpFileOpenMode.create | SftpFileOpenMode.write | SftpFileOpenMode.exclusive - ); - _loader = remoteFile.write( - file.openRead(), - onProgress: (progress) => setState(() => _progress = progress/fileSize) - ); - await _loader?.done; - } - } - - @override - void initState() { - super.initState(); - uploadFiles(); - _loadingFileName = widget.files[0].name; - } - - SftpFileWriter? _loader; - - late String _loadingFileName; - double _progress = 0; - - @override - build(BuildContext context) { - return Align( - alignment: Alignment.bottomCenter, - child: Container( - color: Theme.of(context).colorScheme.secondaryContainer, - child: Padding( - padding: const EdgeInsets.all(10), - child: Column( - spacing: 10, - mainAxisSize: MainAxisSize.min, - children: [ - Row( - spacing: 10, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('Uploading file: $_loadingFileName', style: TextStyle(fontSize: 16),), - TextButton( - onPressed: () { - if (_loader != null) { - _loader!.abort(); - widget.sftpClient.remove('${widget.path}$_loadingFileName'); - } - }, - child: Text('Cancel') - ), - ], - ), - LinearProgressIndicator(value: _progress,) - ], - ), - ), - ), - ); - } -} - diff --git a/lib/widgets/operation_buttons.dart b/lib/widgets/operation_buttons.dart new file mode 100644 index 0000000..d5043d6 --- /dev/null +++ b/lib/widgets/operation_buttons.dart @@ -0,0 +1,118 @@ +import 'package:dartssh2/dartssh2.dart'; +import 'package:flutter/material.dart'; + +class OperationButtons extends StatelessWidget { + const OperationButtons({ + super.key, + required this.dirEntry, + }); + + final SftpName dirEntry; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + onPressed: () { + + }, + icon: Icon(Icons.drive_file_move) + ), + IconButton( + onPressed: () { + + }, + icon: Icon(Icons.copy) + ), + IconButton( + onPressed: () { + final newNameController = TextEditingController(text: dirEntry.filename); + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Rename'), + content: TextField( + controller: newNameController, + autofocus: true, + decoration: InputDecoration( + labelText: 'Enter new name' + ), + ), + actions: [ + TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancel')), + TextButton( + onPressed: () async { + // try { + // await widget.sftpWorker.rename('${path}${dirEntry.filename}', '${widget.path}${newNameController.text}'); + // _listDir(); + // } + // on SftpStatusError catch (e) { + // if (context.mounted) { + // ScaffoldMessenger.of(context).showSnackBar(_buildErrorSnackBar(context, e.message)); + // } + // } + // if (context.mounted) { + // Navigator.pop(context); + // } + // + }, + child: Text('Rename') + ), + + ], + ) + ); + }, + icon: Icon(Icons.drive_file_rename_outline) + ), + IconButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Delete Permanently?'), + content: Text(dirEntry.attr.isDirectory ? 'The contents of this folder will be deleted as well\nThis action cannot be undone' : 'This action cannot be undone'), + actions: [ + TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancel')), + TextButton( + onPressed: () async { + // if (dirEntry.attr.isDirectory) { + // Future removeRecursively (String path) async { + // final dirContents = await widget.sftpWorker.listdir(path); + // for (SftpName entry in dirContents) { + // final fullPath = '$path${entry.filename}'; + // if (entry.attr.isDirectory) { + // await removeRecursively('$fullPath/'); + // await widget.sftpWorker.rmdir('$fullPath/'); + // } + // else { + // await widget.sftpWorker.remove(fullPath); + // } + // } + // await widget.sftpWorker.rmdir(path); + // } + // await removeRecursively('${path}${dirEntry.filename}/'); + // } + // else { + // await widget.sftpWorker.remove('${path}${dirEntry.filename}'); + // } + // _listDir(); + // if (context.mounted) { + // Navigator.pop(context); + // } + }, + child: Text('Yes') + ), + ], + ) + ); + }, + icon: Icon(Icons.delete) + ), + ], + ); + } +} +