mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-01-31 13:25:10 +01:00
#30 fix: context.pop()
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension ContextX on BuildContext {
|
||||
void pop<T>([T? result]) {
|
||||
Navigator.of(this).pop(T);
|
||||
void pop<T extends Object?>([T? result]) {
|
||||
Navigator.of(this).pop<T>(result);
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:r_upgrade/r_upgrade.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
|
||||
import '../data/provider/app.dart';
|
||||
import '../data/res/build_data.dart';
|
||||
import '../data/service/app.dart';
|
||||
import '../locator.dart';
|
||||
import 'utils/navigator.dart';
|
||||
import 'utils/platform.dart';
|
||||
import 'utils/ui.dart';
|
||||
|
||||
|
||||
@@ -30,8 +30,10 @@ enum GenSSHClientStatus {
|
||||
pwd,
|
||||
}
|
||||
|
||||
Future<SSHClient> genClient(ServerPrivateInfo spi,
|
||||
{void Function(GenSSHClientStatus)? onStatus}) async {
|
||||
Future<SSHClient> genClient(
|
||||
ServerPrivateInfo spi, {
|
||||
void Function(GenSSHClientStatus)? onStatus,
|
||||
}) async {
|
||||
final onStatus_ = onStatus ?? (_) {};
|
||||
onStatus_(GenSSHClientStatus.socket);
|
||||
final socket = await SSHSocket.connect(
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
@@ -46,18 +46,18 @@ Future<bool> openUrl(String url) async {
|
||||
return await launchUrl(url.uri, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
|
||||
Future<T?>? showRoundDialog<T>({
|
||||
Future<T?> showRoundDialog<T>({
|
||||
required BuildContext context,
|
||||
Widget? child,
|
||||
List<Widget>? actions,
|
||||
Widget? title,
|
||||
EdgeInsets? padding,
|
||||
bool barrierDismiss = true,
|
||||
}) {
|
||||
return showDialog<T>(
|
||||
}) async {
|
||||
return await showDialog<T>(
|
||||
context: context,
|
||||
barrierDismissible: barrierDismiss,
|
||||
builder: (ctx) {
|
||||
builder: (_) {
|
||||
return CardDialog(
|
||||
title: title,
|
||||
content: child,
|
||||
|
||||
@@ -45,20 +45,21 @@ class ServerProvider extends BusyProvider {
|
||||
return Server(spi, initStatus, null, ServerState.disconnected);
|
||||
}
|
||||
|
||||
Future<void> refreshData(
|
||||
{ServerPrivateInfo? spi, bool onlyFailed = false}) async {
|
||||
Future<void> refreshData({
|
||||
ServerPrivateInfo? spi,
|
||||
bool onlyFailed = false,
|
||||
}) async {
|
||||
if (spi != null) {
|
||||
await _getData(spi);
|
||||
return;
|
||||
}
|
||||
final futures = _servers.values.map((s) async {
|
||||
await Future.wait(_servers.values.map((s) async {
|
||||
if (onlyFailed) {
|
||||
if (s.state != ServerState.failed) return;
|
||||
_limiter.resetTryTimes(s.spi.id);
|
||||
}
|
||||
return await _getData(s.spi);
|
||||
});
|
||||
await Future.wait(futures);
|
||||
}));
|
||||
}
|
||||
|
||||
Future<void> startAutoRefresh() async {
|
||||
@@ -117,13 +118,14 @@ class ServerProvider extends BusyProvider {
|
||||
}
|
||||
|
||||
Future<void> updateServer(
|
||||
ServerPrivateInfo old, ServerPrivateInfo newSpi) async {
|
||||
ServerPrivateInfo old,
|
||||
ServerPrivateInfo newSpi,
|
||||
) async {
|
||||
_servers.remove(old.id);
|
||||
_store.update(old, newSpi);
|
||||
_servers[newSpi.id] = genServer(newSpi);
|
||||
_servers[newSpi.id]?.client = await genClient(newSpi);
|
||||
notifyListeners();
|
||||
refreshData(spi: newSpi);
|
||||
await refreshData(spi: newSpi);
|
||||
}
|
||||
|
||||
Future<void> _getData(ServerPrivateInfo spi) async {
|
||||
@@ -132,6 +134,8 @@ class ServerProvider extends BusyProvider {
|
||||
if (s == null) return;
|
||||
|
||||
var raw = '';
|
||||
var segments = <String>[];
|
||||
|
||||
try {
|
||||
final state = s.state;
|
||||
if (state.shouldConnect) {
|
||||
@@ -167,23 +171,31 @@ class ServerProvider extends BusyProvider {
|
||||
if (s.client == null) return;
|
||||
// run script to get server status
|
||||
raw = await s.client!.run("sh $shellPath").string;
|
||||
final segments = raw.split(seperator).map((e) => e.trim()).toList();
|
||||
segments = raw.split(seperator).map((e) => e.trim()).toList();
|
||||
if (raw.isEmpty || segments.length != CmdType.values.length) {
|
||||
s.state = ServerState.failed;
|
||||
if (s.status.failedInfo == null || s.status.failedInfo!.isEmpty) {
|
||||
if (s.status.failedInfo?.isEmpty ?? true) {
|
||||
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
s.state = ServerState.failed;
|
||||
s.status.failedInfo = e.toString();
|
||||
rethrow;
|
||||
} finally {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
try {
|
||||
final req = ServerStatusUpdateReq(s.status, segments);
|
||||
s.status = await compute(getStatus, req);
|
||||
// Comment for debug
|
||||
// s.status = await getStatus(req);
|
||||
} catch (e) {
|
||||
s.state = ServerState.failed;
|
||||
s.status.failedInfo = '$e\n$raw';
|
||||
_logger.warning(e);
|
||||
s.status.failedInfo = 'Parse failed: $e\n\n$raw';
|
||||
rethrow;
|
||||
} finally {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 288;
|
||||
static const int build = 293;
|
||||
static const String engine = "3.7.11";
|
||||
static const String buildAt = "2023-05-07 20:47:03.124092";
|
||||
static const int modifications = 1;
|
||||
static const String buildAt = "2023-05-09 19:48:09.523377";
|
||||
static const int modifications = 4;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/data/res/path.dart';
|
||||
|
||||
import '../../core/extension/colorx.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../core/utils/ui.dart';
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/data/provider/app.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../data/model/pkg/upgrade_info.dart';
|
||||
|
||||
@@ -5,9 +5,9 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/extension/numx.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../../core/route.dart';
|
||||
|
||||
@@ -4,7 +4,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
|
||||
import '../../../core/route.dart';
|
||||
import '../../../core/utils/ui.dart';
|
||||
@@ -114,21 +115,21 @@ class _ServerPageState extends State<ServerPage>
|
||||
if (si == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
return RoundRectCard(
|
||||
InkWell(
|
||||
onLongPress: () => AppRoute(
|
||||
ServerEditPage(
|
||||
spi: si.spi,
|
||||
),
|
||||
'Edit server info page')
|
||||
.go(context),
|
||||
child: Padding(
|
||||
return GestureDetector(
|
||||
onLongPress: () => AppRoute(
|
||||
ServerEditPage(spi: si.spi),
|
||||
'Edit server info page',
|
||||
).go(context),
|
||||
child: RoundRectCard(
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(13),
|
||||
child: _buildRealServerCard(si.status, si.spi.name, si.state, si.spi),
|
||||
),
|
||||
onTap: () => AppRoute(ServerDetailPage(si.spi.id), 'server detail page')
|
||||
.go(context),
|
||||
),
|
||||
onTap: () => AppRoute(
|
||||
ServerDetailPage(si.spi.id),
|
||||
'server detail page',
|
||||
).go(context),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,7 +173,14 @@ class _ServerPageState extends State<ServerPage>
|
||||
onTap: () => showRoundDialog(
|
||||
context: context,
|
||||
title: Text(_s.error),
|
||||
child: Text(ss.failedInfo ?? ''),
|
||||
child: Text(ss.failedInfo ?? _s.unknownError),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () =>
|
||||
copy(ss.failedInfo ?? _s.unknownError),
|
||||
child: Text(_s.copy),
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
_s.clickSee,
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/data/model/app/tab.dart';
|
||||
|
||||
import '../../core/utils/misc.dart';
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
|
||||
import '../../../core/extension/numx.dart';
|
||||
import '../../../core/extension/stringx.dart';
|
||||
|
||||
@@ -3,8 +3,7 @@ import 'dart:typed_data';
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
|
||||
import '../../../core/extension/numx.dart';
|
||||
import '../../../core/extension/stringx.dart';
|
||||
@@ -22,6 +21,7 @@ import '../../../data/res/ui.dart';
|
||||
import '../../../data/store/private_key.dart';
|
||||
import '../../../locator.dart';
|
||||
import '../../widget/fade_in.dart';
|
||||
import '../../widget/input_field.dart';
|
||||
import '../../widget/two_line_text.dart';
|
||||
import 'downloading.dart';
|
||||
|
||||
@@ -138,7 +138,7 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
return IconButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
onPressed: () async {
|
||||
final p = await showRoundDialog<String?>(
|
||||
final p = await showRoundDialog<String>(
|
||||
context: context,
|
||||
title: Text(_s.goto),
|
||||
child: Column(
|
||||
@@ -146,7 +146,6 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
children: [
|
||||
Input(
|
||||
label: _s.path,
|
||||
hint: '/',
|
||||
onSubmitted: (value) => context.pop(value),
|
||||
),
|
||||
],
|
||||
@@ -154,19 +153,17 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(_s.cancel),
|
||||
child: Text(_s.close),
|
||||
)
|
||||
],
|
||||
);
|
||||
|
||||
if (p != null) {
|
||||
if (p.isEmpty) {
|
||||
showSnackBar(context, Text(_s.fieldMustNotEmpty));
|
||||
return;
|
||||
}
|
||||
_status.path?.update(p);
|
||||
listDir(path: p);
|
||||
// p == null || p.isEmpty
|
||||
if (p?.isEmpty ?? true) {
|
||||
return;
|
||||
}
|
||||
_status.path?.update(p!);
|
||||
listDir(path: p);
|
||||
},
|
||||
icon: const Icon(Icons.gps_fixed),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../../core/utils/ui.dart';
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/utils/navigator.dart';
|
||||
import 'package:toolbox/core/extension/navigator.dart';
|
||||
import 'package:xterm/xterm.dart' hide TerminalColors;
|
||||
|
||||
import '../../core/utils/platform.dart';
|
||||
|
||||
@@ -8,7 +8,7 @@ class Input extends StatelessWidget {
|
||||
final int? minLines;
|
||||
final String? hint;
|
||||
final String? label;
|
||||
final Function(String)? onSubmitted;
|
||||
final void Function(String)? onSubmitted;
|
||||
final bool obscureText;
|
||||
final IconData? icon;
|
||||
final TextInputType? type;
|
||||
|
||||
Reference in New Issue
Block a user