diff --git a/lib/app.dart b/lib/app.dart index a0dbc1e2..4aa74d8f 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -56,6 +56,9 @@ class MyApp extends StatelessWidget { appBarTheme: const AppBarTheme( backgroundColor: Colors.black, ), + dialogTheme: const DialogTheme( + backgroundColor: Colors.black, + ), bottomSheetTheme: const BottomSheetThemeData( backgroundColor: Colors.black, ), @@ -68,6 +71,9 @@ class MyApp extends StatelessWidget { navigationBarTheme: const NavigationBarThemeData( backgroundColor: Colors.black, ), + popupMenuTheme: const PopupMenuThemeData( + color: Colors.black, + ), ), home: const HomePage(), ); diff --git a/lib/core/utils/misc.dart b/lib/core/utils/misc.dart index e8468da9..3e69dd3a 100644 --- a/lib/core/utils/misc.dart +++ b/lib/core/utils/misc.dart @@ -73,3 +73,7 @@ String getTime(int? unixMill) { .toString() .replaceFirst('.000', ''); } + +String pathJoin(String path1, String path2) { + return path1 + (path1.endsWith('/') ? '' : '/') + path2; +} diff --git a/lib/data/model/app/path_with_prefix.dart b/lib/data/model/app/path_with_prefix.dart index 52ccd374..1ef9db54 100644 --- a/lib/data/model/app/path_with_prefix.dart +++ b/lib/data/model/app/path_with_prefix.dart @@ -1,3 +1,5 @@ +import 'package:toolbox/core/utils/misc.dart'; + class PathWithPrefix { final String _prefixPath; String _path = '/'; @@ -19,7 +21,7 @@ class PathWithPrefix { _path = '/'; return; } - _path = _path + (_path.endsWith('/') ? '' : '/') + newPath; + _path = pathJoin(_path, newPath); } bool undo() { diff --git a/lib/data/model/sftp/absolute_path.dart b/lib/data/model/sftp/absolute_path.dart index 83e5576f..11c92d25 100644 --- a/lib/data/model/sftp/absolute_path.dart +++ b/lib/data/model/sftp/absolute_path.dart @@ -1,3 +1,5 @@ +import 'package:toolbox/core/utils/misc.dart'; + class AbsolutePath { String _path; String get path => _path; @@ -22,7 +24,7 @@ class AbsolutePath { _path = newPath; return; } - _path = _path + (_path.endsWith('/') ? '' : '/') + newPath; + _path = pathJoin(_path, newPath); } bool undo() { diff --git a/lib/view/page/sftp/downloaded.dart b/lib/view/page/sftp/downloaded.dart index addbc0f3..24f14711 100644 --- a/lib/view/page/sftp/downloaded.dart +++ b/lib/view/page/sftp/downloaded.dart @@ -24,7 +24,9 @@ import '../../widget/fade_in.dart'; import 'downloading.dart'; class SFTPDownloadedPage extends StatefulWidget { - const SFTPDownloadedPage({Key? key}) : super(key: key); + final bool isPickFile; + const SFTPDownloadedPage({Key? key, this.isPickFile = false}) + : super(key: key); @override State createState() => _SFTPDownloadedPageState(); @@ -128,9 +130,9 @@ class _SFTPDownloadedPageState extends State { .substring(0, stat.modified.toString().length - 4), style: grey, ), - onTap: () { + onTap: () async { if (!isDir) { - showFileActionDialog(file); + await showFileActionDialog(file); return; } _path!.update(fileName); @@ -141,8 +143,24 @@ class _SFTPDownloadedPageState extends State { ); } - void showFileActionDialog(FileSystemEntity file) { + Future showFileActionDialog(FileSystemEntity file) async { final fileName = file.path.split('/').last; + if (widget.isPickFile) { + await showRoundDialog( + context: context, + title: Text(_s.pickFile), + child: Text(fileName), + actions: [ + TextButton( + onPressed: () { + context.pop(); + context.pop(file.path); + }, + child: Text(_s.ok), + ), + ]); + return; + } showRoundDialog( context: context, child: Column( diff --git a/lib/view/page/sftp/view.dart b/lib/view/page/sftp/view.dart index c725f355..1f5d7329 100644 --- a/lib/view/page/sftp/view.dart +++ b/lib/view/page/sftp/view.dart @@ -8,6 +8,7 @@ import 'package:toolbox/core/extension/navigator.dart'; import 'package:toolbox/core/extension/sftpfile.dart'; import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/view/page/editor.dart'; +import 'package:toolbox/view/page/sftp/downloaded.dart'; import '../../../core/extension/numx.dart'; import '../../../core/extension/stringx.dart'; @@ -104,6 +105,7 @@ class _SFTPPageState extends State { ), _buildAddBtn(), _buildGotoBtn(), + _buildUploadBtn(), ], ) ], @@ -112,6 +114,31 @@ class _SFTPPageState extends State { ); } + Widget _buildUploadBtn() { + return IconButton( + onPressed: () async { + final path = await AppRoute( + const SFTPDownloadedPage( + isPickFile: true, + ), + 'sftp dled pick') + .go(context); + if (path == null) { + return; + } + final remotePath = _status.path?.path; + if (remotePath == null) { + showSnackBar(context, const Text('remote path is null')); + return; + } + locator().add( + SftpReqItem(widget.spi, remotePath, path), + SftpReqType.upload, + ); + }, + icon: const Icon(Icons.upload_file)); + } + Widget _buildAddBtn() { return IconButton( onPressed: (() => showRoundDialog( @@ -534,7 +561,7 @@ class _SFTPPageState extends State { String _getRemotePath(SftpName name) { final prePath = _status.path!.path; - return prePath + (prePath.endsWith('/') ? '' : '/') + name.filename; + return pathJoin(prePath, name.filename); } Future _listDir({String? path, SSHClient? client}) async {