opt.: server tab

This commit is contained in:
lollipopkit
2023-12-02 17:35:14 +08:00
parent fc0c9b3a49
commit 440dabfca8
5 changed files with 101 additions and 71 deletions

View File

@@ -586,7 +586,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -596,7 +596,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -720,7 +720,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -730,7 +730,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -748,7 +748,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -758,7 +758,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -779,7 +779,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -792,7 +792,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -818,7 +818,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -831,7 +831,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -854,7 +854,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -867,7 +867,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -890,7 +890,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -902,7 +902,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -931,7 +931,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -943,7 +943,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;
@@ -969,7 +969,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 653; CURRENT_PROJECT_VERSION = 654;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -981,7 +981,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.653; MARKETING_VERSION = 1.0.654;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 653; static const int build = 654;
static const String engine = "3.16.0"; static const String engine = "3.16.2";
static const String buildAt = "2023-11-27 19:18:56"; static const String buildAt = "2023-12-02 00:21:29";
static const int modifications = 3; static const int modifications = 2;
static const int script = 30; static const int script = 31;
} }

View File

@@ -39,12 +39,7 @@ class _ServerPageState extends State<ServerPage>
with AutomaticKeepAliveClientMixin, AfterLayoutMixin { with AutomaticKeepAliveClientMixin, AfterLayoutMixin {
late MediaQueryData _media; late MediaQueryData _media;
final _flipedCardIds = <String>{}; final _cardsStatus = <String, _CardNotifier>{};
final _netViewType = <String, NetViewType>{};
/// If true, display IO speed
final _diskViewSpeed = <String, bool>{};
String? _tag; String? _tag;
bool _useDoubleColumn = false; bool _useDoubleColumn = false;
@@ -88,7 +83,7 @@ class _ServerPageState extends State<ServerPage>
final filtered = _filterServers(pro); final filtered = _filterServers(pro);
if (_useDoubleColumn && if (_useDoubleColumn &&
Stores.setting.doubleColumnServersPage.fetch()) { Stores.setting.doubleColumnServersPage.fetch()) {
return _buildBodyMedium(pro); return _buildBodyMedium(pro: pro, filtered: filtered);
} }
return _buildBodySmall(provider: pro, filtered: filtered); return _buildBodySmall(provider: pro, filtered: filtered);
}, },
@@ -138,8 +133,10 @@ class _ServerPageState extends State<ServerPage>
); );
} }
Widget _buildBodyMedium(ServerProvider pro) { Widget _buildBodyMedium({
final filtered = _filterServers(pro); required ServerProvider pro,
required List<String> filtered,
}) {
final left = filtered.where((e) => filtered.indexOf(e) % 2 == 0).toList(); final left = filtered.where((e) => filtered.indexOf(e) % 2 == 0).toList();
final right = filtered.where((e) => filtered.indexOf(e) % 2 == 1).toList(); final right = filtered.where((e) => filtered.indexOf(e) % 2 == 1).toList();
return Column( return Column(
@@ -191,13 +188,11 @@ class _ServerPageState extends State<ServerPage>
}, },
onLongPress: () { onLongPress: () {
if (srv.state == ServerState.finished) { if (srv.state == ServerState.finished) {
setState(() { final id = srv.spi.id;
if (_flipedCardIds.contains(srv.spi.id)) { final cardStatus = getCardNoti(id);
_flipedCardIds.remove(srv.spi.id); cardStatus.value = cardStatus.value.copyWith(
} else { flip: !cardStatus.value.flip,
_flipedCardIds.add(srv.spi.id); );
}
});
} else { } else {
AppRoute.serverEdit(spi: srv.spi).go(context); AppRoute.serverEdit(spi: srv.spi).go(context);
} }
@@ -220,26 +215,32 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildRealServerCard(Server srv) { Widget _buildRealServerCard(Server srv) {
final id = srv.spi.id;
final cardStatus = getCardNoti(id);
final title = _buildServerCardTitle(srv.status, srv.state, srv.spi); final title = _buildServerCardTitle(srv.status, srv.state, srv.spi);
final List<Widget> children = [title];
return AnimatedContainer(
duration: const Duration(milliseconds: 377),
curve: Curves.fastEaseInToSlowEaseOut,
height: _calcCardHeight(srv.state, cardStatus.value.flip),
child: ValueBuilder(
listenable: cardStatus,
build: () {
final List<Widget> children = [title];
if (srv.state == ServerState.finished) { if (srv.state == ServerState.finished) {
if (_flipedCardIds.contains(srv.spi.id)) { if (cardStatus.value.flip) {
children.addAll(_buildFlipedCard(srv)); children.addAll(_buildFlipedCard(srv));
} else { } else {
children.addAll(_buildNormalCard(srv.status, srv.spi)); children.addAll(_buildNormalCard(srv.status, srv.spi));
} }
} }
return Column(
return AnimatedContainer(
duration: const Duration(milliseconds: 377),
curve: Curves.fastEaseInToSlowEaseOut,
height: _calcCardHeight(srv.state, srv.spi.id),
child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: children, children: children,
);
},
), ),
); );
} }
@@ -431,11 +432,12 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildDisk(ServerStatus ss, String id) { Widget _buildDisk(ServerStatus ss, String id) {
final cardNoti = getCardNoti(id);
return ValueBuilder( return ValueBuilder(
listenable: Stores.setting.serverTabPreferDiskAmount.listenable(), listenable: cardNoti,
build: () { build: () {
final rootDisk = findRootDisk(ss.disk); final rootDisk = findRootDisk(ss.disk);
final isSpeed = _diskViewSpeed[id] ?? final isSpeed = cardNoti.value.diskIO ??
!Stores.setting.serverTabPreferDiskAmount.fetch(); !Stores.setting.serverTabPreferDiskAmount.fetch();
final (r, w) = ss.diskIO.getAllSpeed(); final (r, w) = ss.diskIO.getAllSpeed();
@@ -449,9 +451,7 @@ class _ServerPageState extends State<ServerPage>
isSpeed ? '${l10n.read}:\n$r' : 'Total:\n${rootDisk?.size}', isSpeed ? '${l10n.read}:\n$r' : 'Total:\n${rootDisk?.size}',
isSpeed ? '${l10n.write}:\n$w' : 'Used:\n${rootDisk?.usedPercent}%', isSpeed ? '${l10n.write}:\n$w' : 'Used:\n${rootDisk?.usedPercent}%',
onTap: () { onTap: () {
setState(() { cardNoti.value = cardNoti.value.copyWith(diskIO: !isSpeed);
_diskViewSpeed[id] = !isSpeed;
});
}, },
key: ValueKey(isSpeed), key: ValueKey(isSpeed),
), ),
@@ -461,7 +461,8 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildNet(ServerStatus ss, String id) { Widget _buildNet(ServerStatus ss, String id) {
final type = _netViewType[id] ?? Stores.setting.netViewType.fetch(); final cardNoti = getCardNoti(id);
final type = cardNoti.value.net ?? Stores.setting.netViewType.fetch();
final (a, b) = type.build(ss); final (a, b) = type.build(ss);
return AnimatedSwitcher( return AnimatedSwitcher(
duration: const Duration(milliseconds: 377), duration: const Duration(milliseconds: 377),
@@ -472,9 +473,7 @@ class _ServerPageState extends State<ServerPage>
a, a,
b, b,
onTap: () { onTap: () {
setState(() { cardNoti.value = cardNoti.value.copyWith(net: type.next);
_netViewType[id] = type.next;
});
}, },
key: ValueKey(type), key: ValueKey(type),
), ),
@@ -585,11 +584,11 @@ class _ServerPageState extends State<ServerPage>
} }
} }
double _calcCardHeight(ServerState cs, String id) { double _calcCardHeight(ServerState cs, bool flip) {
if (cs != ServerState.finished) { if (cs != ServerState.finished) {
return 23.0; return 23.0;
} }
if (_flipedCardIds.contains(id)) { if (flip) {
return 80.0; return 80.0;
} }
if (Stores.setting.moveOutServerTabFuncBtns.fetch() && if (Stores.setting.moveOutServerTabFuncBtns.fetch() &&
@@ -619,4 +618,35 @@ class _ServerPageState extends State<ServerPage>
], ],
); );
} }
_CardNotifier getCardNoti(String id) => _cardsStatus.putIfAbsent(
id,
() => _CardNotifier(const _CardStatus()),
);
}
typedef _CardNotifier = ValueNotifier<_CardStatus>;
class _CardStatus {
final bool flip;
final bool? diskIO;
final NetViewType? net;
const _CardStatus({
this.flip = false,
this.diskIO,
this.net,
});
_CardStatus copyWith({
bool? flip,
bool? diskIO,
NetViewType? net,
}) {
return _CardStatus(
flip: flip ?? this.flip,
diskIO: diskIO ?? this.diskIO,
net: net ?? this.net,
);
}
} }

View File

@@ -312,7 +312,7 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
return _terminal.buffer.getText(range); return _terminal.buffer.getText(range);
} }
void _write(String p0) { void _writeLn(String p0) {
_terminal.write('$p0\r\n'); _terminal.write('$p0\r\n');
} }
@@ -329,11 +329,11 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
} }
Future<void> _initTerminal() async { Future<void> _initTerminal() async {
_write('Connecting...\r\n'); _writeLn('Connecting...\r\n');
if (_client == null) { if (_client == null) {
await Pros.server.refreshData(spi: widget.spi); await Pros.server.refreshData(spi: widget.spi);
} }
_write('Starting shell...\r\n'); _writeLn('Starting shell...\r\n');
final session = await _client?.shell( final session = await _client?.shell(
pty: SSHPtyConfig( pty: SSHPtyConfig(
@@ -345,7 +345,7 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
_setupDiscontinuityTimer(); _setupDiscontinuityTimer();
if (session == null) { if (session == null) {
_write(_server?.status.err ?? 'Null session'); _writeLn(_server?.status.err ?? 'Null session');
return; return;
} }
@@ -402,7 +402,7 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
void _catchTimeout() { void _catchTimeout() {
_discontinuityTimer?.cancel(); _discontinuityTimer?.cancel();
if (!mounted) return; if (!mounted) return;
_write('\n\nConnection lost\r\n'); _writeLn('\n\nConnection lost\r\n');
context.showRoundDialog( context.showRoundDialog(
title: Text(l10n.attention), title: Text(l10n.attention),
child: Text('${l10n.disconnected}\n${l10n.goBackQ}'), child: Text('${l10n.disconnected}\n${l10n.goBackQ}'),