sending progress to ui with very epic animated upload progress
This commit is contained in:
parent
b3b2fc8895
commit
ce6374d302
3 changed files with 70 additions and 13 deletions
|
@ -11,6 +11,7 @@ class MainApp extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorSchemeSeed: Colors.teal,
|
||||
|
|
|
@ -21,6 +21,8 @@ class _SftpExplorerState extends State<SftpExplorer> {
|
|||
bool _isLoading = true;
|
||||
late List<SftpName> _dirContents;
|
||||
|
||||
double? _progress;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
@ -45,7 +47,29 @@ class _SftpExplorerState extends State<SftpExplorer> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 75,
|
||||
title: Text('Explorer'),
|
||||
elevation: 2,
|
||||
actionsPadding: EdgeInsets.only(right: 20),
|
||||
actions: [
|
||||
if (_progress != null)
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 0, end: _progress),
|
||||
duration: Duration(milliseconds: 300),
|
||||
builder: (context, value, _) => CircularProgressIndicator(strokeWidth: 3, value: value,)
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
icon: Icon(Icons.upload)
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: _buildFABs(context),
|
||||
body: _isLoading ? Center(child: CircularProgressIndicator()) : ListView.builder(
|
||||
|
@ -234,7 +258,18 @@ class _SftpExplorerState extends State<SftpExplorer> {
|
|||
final files = await openFiles();
|
||||
filePaths = files.map((file) => file.path).toList();
|
||||
}
|
||||
await widget.sftpWorker.uploadFiles(widget.path, filePaths);
|
||||
try {
|
||||
await for (final progress in widget.sftpWorker.uploadFiles(widget.path, filePaths)) {
|
||||
print(progress);
|
||||
setState(() => _progress = progress);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(_buildErrorSnackBar(context, e.toString()));
|
||||
}
|
||||
}
|
||||
setState(() => _progress = null);
|
||||
_listDir();
|
||||
},
|
||||
child: Icon(Icons.upload),
|
||||
|
|
|
@ -24,7 +24,7 @@ class SftpWorker {
|
|||
|
||||
final ReceivePort _responses;
|
||||
final SendPort _commands;
|
||||
final Map<int, Completer<Object>> _activeRequests = {};
|
||||
final Map<int, dynamic> _activeRequests = {};
|
||||
int _idCounter = 0;
|
||||
|
||||
SftpWorker._(this._responses, this._commands) {
|
||||
|
@ -98,24 +98,31 @@ class SftpWorker {
|
|||
'$path${basename(filePath)}',
|
||||
mode: SftpFileOpenMode.create | SftpFileOpenMode.write | SftpFileOpenMode.exclusive
|
||||
);
|
||||
bool timeout = true;
|
||||
await remoteFile.write(
|
||||
file.openRead().cast(),
|
||||
onProgress: (progress) {
|
||||
print(progress/fileSize);
|
||||
if (timeout) {
|
||||
timeout = false;
|
||||
sendPort.send((id, progress/fileSize));
|
||||
Future.delayed(Duration(seconds: 2), () => timeout = true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
on SftpStatusError catch (e) {
|
||||
sendPort.send((id, RemoteError(e.message, '')));
|
||||
}
|
||||
sendPort.send((id, 1.0));
|
||||
}
|
||||
sendPort.send((id, 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _sftpResponseHandler(dynamic message) {
|
||||
final (int id, Object response) = message;
|
||||
|
||||
if (_activeRequests[id] is Completer) {
|
||||
final completer = _activeRequests.remove(id)!;
|
||||
|
||||
if (response is RemoteError) {
|
||||
|
@ -125,6 +132,20 @@ class SftpWorker {
|
|||
completer.complete(response);
|
||||
}
|
||||
}
|
||||
else if (_activeRequests[id] is StreamController) {
|
||||
final controller = _activeRequests[id] as StreamController;
|
||||
if (response is RemoteError) {
|
||||
controller.addError(response);
|
||||
}
|
||||
else {
|
||||
controller.add(response);
|
||||
if (response == 1) {
|
||||
controller.close();
|
||||
_activeRequests.remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<List<SftpName>> listdir(String path) async {
|
||||
|
@ -136,12 +157,12 @@ class SftpWorker {
|
|||
}
|
||||
|
||||
|
||||
Future<void> uploadFiles(String path, List<String> filePaths) async {
|
||||
final completer = Completer<Object>.sync();
|
||||
Stream<double> uploadFiles(String path, List<String> filePaths) {
|
||||
final controller = StreamController<double>();
|
||||
final id = _idCounter++;
|
||||
_activeRequests[id] = completer;
|
||||
_activeRequests[id] = controller;
|
||||
_commands.send((id, UploadFiles(path, filePaths)));
|
||||
await completer.future;
|
||||
return controller.stream;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue