#86 fix: docker loading forever

This commit is contained in:
lollipopkit
2023-08-08 20:31:35 +08:00
parent 173b7f6362
commit 58fbd62779
4 changed files with 43 additions and 34 deletions

View File

@@ -9,6 +9,7 @@ import 'package:url_launcher/url_launcher.dart';
import '../../data/model/server/snippet.dart'; import '../../data/model/server/snippet.dart';
import '../../data/provider/snippet.dart'; import '../../data/provider/snippet.dart';
import '../../data/res/ui.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../../view/page/snippet/edit.dart'; import '../../view/page/snippet/edit.dart';
import '../../view/widget/picker.dart'; import '../../view/widget/picker.dart';
@@ -69,6 +70,14 @@ Future<T?> showRoundDialog<T>({
); );
} }
void showLoadingDialog(BuildContext context, {bool barrierDismiss = false}) {
showRoundDialog(
context: context,
child: centerSizedLoading,
barrierDismiss: barrierDismiss,
);
}
Widget buildSwitch( Widget buildSwitch(
BuildContext context, BuildContext context,
StoreProperty<bool> prop, { StoreProperty<bool> prop, {

View File

@@ -2,10 +2,10 @@ import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:toolbox/core/extension/ssh_client.dart';
import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/provider_base.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/docker/image.dart'; import 'package:toolbox/data/model/docker/image.dart';
import 'package:toolbox/data/model/docker/ps.dart'; import 'package:toolbox/data/model/docker/ps.dart';
@@ -22,7 +22,7 @@ final _dockerPrefixReg = RegExp(r'(sudo )?docker ');
final _logger = Logger('DOCKER'); final _logger = Logger('DOCKER');
class DockerProvider extends BusyProvider { class DockerProvider extends ChangeNotifier {
final _dockerStore = locator<DockerStore>(); final _dockerStore = locator<DockerStore>();
SSHClient? client; SSHClient? client;
@@ -56,9 +56,6 @@ class DockerProvider extends BusyProvider {
} }
Future<void> refresh() async { Future<void> refresh() async {
if (isBusy) return;
setBusyState();
var raw = ''; var raw = '';
await client!.exec( await client!.exec(
AppShellFuncType.docker.exec, AppShellFuncType.docker.exec,
@@ -68,7 +65,7 @@ class DockerProvider extends BusyProvider {
if (raw.contains(_dockerNotFound)) { if (raw.contains(_dockerNotFound)) {
error = DockerErr(type: DockerErrType.notInstalled); error = DockerErr(type: DockerErrType.notInstalled);
setBusyState(false); notifyListeners();
return; return;
} }
@@ -76,7 +73,7 @@ class DockerProvider extends BusyProvider {
final segments = raw.split(seperator); final segments = raw.split(seperator);
if (segments.length != dockerCmds.length) { if (segments.length != dockerCmds.length) {
error = DockerErr(type: DockerErrType.segmentsNotMatch); error = DockerErr(type: DockerErrType.segmentsNotMatch);
setBusyState(false); notifyListeners();
return; return;
} }
@@ -98,9 +95,8 @@ class DockerProvider extends BusyProvider {
message: '$psRaw\n-\n$e', message: '$psRaw\n-\n$e',
); );
_logger.warning('parse docker ps: $psRaw', e); _logger.warning('parse docker ps: $psRaw', e);
rethrow;
} finally { } finally {
setBusyState(false); notifyListeners();
} }
// Parse docker images // Parse docker images
@@ -116,9 +112,8 @@ class DockerProvider extends BusyProvider {
message: '$imageRaw\n-\n$e', message: '$imageRaw\n-\n$e',
); );
_logger.warning('parse docker images: $imageRaw', e); _logger.warning('parse docker images: $imageRaw', e);
rethrow;
} finally { } finally {
setBusyState(false); notifyListeners();
} }
// Parse docker stats // Parse docker stats
@@ -141,9 +136,8 @@ class DockerProvider extends BusyProvider {
message: '$statsRaw\n-\n$e', message: '$statsRaw\n-\n$e',
); );
_logger.warning('parse docker stats: $statsRaw', e); _logger.warning('parse docker stats: $statsRaw', e);
rethrow;
} finally { } finally {
setBusyState(false); notifyListeners();
} }
} }
@@ -175,7 +169,6 @@ class DockerProvider extends BusyProvider {
if (!cmd.startsWith(_dockerPrefixReg)) { if (!cmd.startsWith(_dockerPrefixReg)) {
return DockerErr(type: DockerErrType.cmdNoPrefix); return DockerErr(type: DockerErrType.cmdNoPrefix);
} }
setBusyState();
runLog = ''; runLog = '';
final errs = <String>[]; final errs = <String>[];
@@ -191,16 +184,15 @@ class DockerProvider extends BusyProvider {
}, },
); );
runLog = null; runLog = null;
notifyListeners();
if (code != 0) { if (code != 0) {
setBusyState(false);
return DockerErr( return DockerErr(
type: DockerErrType.unknown, type: DockerErrType.unknown,
message: errs.join('\n').trim(), message: errs.join('\n').trim(),
); );
} }
await refresh(); await refresh();
setBusyState(false);
return null; return null;
} }

View File

@@ -70,7 +70,11 @@ class _DockerManagePageState extends State<DockerManagePage> {
title: TwoLineText(up: 'Docker', down: widget.spi.name), title: TwoLineText(up: 'Docker', down: widget.spi.name),
actions: [ actions: [
IconButton( IconButton(
onPressed: _docker.refresh, onPressed: () async {
showLoadingDialog(context);
await _docker.refresh();
context.pop();
},
icon: const Icon(Icons.refresh), icon: const Icon(Icons.refresh),
) )
], ],
@@ -153,7 +157,9 @@ class _DockerManagePageState extends State<DockerManagePage> {
TextButton( TextButton(
onPressed: () async { onPressed: () async {
context.pop(); context.pop();
showLoadingDialog(context);
final result = await _docker.run(cmd); final result = await _docker.run(cmd);
context.pop();
if (result != null) { if (result != null) {
showSnackBar(context, Text(result.message ?? _s.unknownError)); showSnackBar(context, Text(result.message ?? _s.unknownError));
} }
@@ -331,7 +337,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
} }
Widget _buildLoading() { Widget _buildLoading() {
if (!_docker.isBusy) return nil; if (_docker.runLog == null) return nil;
return Padding( return Padding(
padding: const EdgeInsets.all(17), padding: const EdgeInsets.all(17),
child: Column( child: Column(
@@ -409,11 +415,11 @@ class _DockerManagePageState extends State<DockerManagePage> {
'${item.name} - ${item.status}', '${item.name} - ${item.status}',
style: textSize13Grey, style: textSize13Grey,
), ),
trailing: _buildMoreBtn(item, _docker.isBusy), trailing: _buildMoreBtn(item),
); );
} }
Widget _buildMoreBtn(DockerPsItem dItem, bool busy) { Widget _buildMoreBtn(DockerPsItem dItem) {
return PopupMenu( return PopupMenu(
items: DockerMenuType.items(dItem.running) items: DockerMenuType.items(dItem.running)
.map( .map(
@@ -421,10 +427,6 @@ class _DockerManagePageState extends State<DockerManagePage> {
) )
.toList(), .toList(),
onSelected: (DockerMenuType item) async { onSelected: (DockerMenuType item) async {
if (busy) {
showSnackBar(context, Text(_s.isBusy));
return;
}
switch (item) { switch (item) {
case DockerMenuType.rm: case DockerMenuType.rm:
showRoundDialog( showRoundDialog(
@@ -433,9 +435,11 @@ class _DockerManagePageState extends State<DockerManagePage> {
child: Text(_s.sureDelete(dItem.name)), child: Text(_s.sureDelete(dItem.name)),
actions: [ actions: [
TextButton( TextButton(
onPressed: () { onPressed: () async {
context.pop();
showLoadingDialog(context);
await _docker.delete(dItem.containerId);
context.pop(); context.pop();
_docker.delete(dItem.containerId);
}, },
child: Text(_s.ok), child: Text(_s.ok),
) )
@@ -443,13 +447,19 @@ class _DockerManagePageState extends State<DockerManagePage> {
); );
break; break;
case DockerMenuType.start: case DockerMenuType.start:
_docker.start(dItem.containerId); showLoadingDialog(context);
await _docker.start(dItem.containerId);
context.pop();
break; break;
case DockerMenuType.stop: case DockerMenuType.stop:
_docker.stop(dItem.containerId); showLoadingDialog(context);
await _docker.stop(dItem.containerId);
context.pop();
break; break;
case DockerMenuType.restart: case DockerMenuType.restart:
_docker.restart(dItem.containerId); showLoadingDialog(context);
await _docker.restart(dItem.containerId);
context.pop();
break; break;
case DockerMenuType.logs: case DockerMenuType.logs:
AppRoute( AppRoute(

View File

@@ -395,7 +395,7 @@ class _SftpPageState extends State<SftpPage> {
SftpReqType.download, SftpReqType.download,
); );
_sftp.add(req, completer: completer); _sftp.add(req, completer: completer);
showRoundDialog(context: context, child: centerSizedLoading); showLoadingDialog(context);
await completer.future; await completer.future;
context.pop(); context.pop();
@@ -458,10 +458,8 @@ class _SftpPageState extends State<SftpPage> {
TextButton( TextButton(
onPressed: () async { onPressed: () async {
context.pop(); context.pop();
showRoundDialog( showLoadingDialog(
context: context, context
child: centerSizedLoading,
barrierDismiss: false,
); );
final remotePath = _getRemotePath(file); final remotePath = _getRemotePath(file);
try { try {