fix: can't quit app

This commit is contained in:
LollipopKit
2022-12-20 13:40:48 +08:00
parent cfd28c3009
commit 6bda94bd7b
17 changed files with 353 additions and 380 deletions

View File

@@ -6,6 +6,7 @@ import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/provider/apt.dart'; import 'package:toolbox/data/provider/apt.dart';
import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/res/font_style.dart';
import 'package:toolbox/data/res/url.dart'; import 'package:toolbox/data/res/url.dart';
import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/generated/l10n.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
@@ -26,18 +27,17 @@ class AptManagePage extends StatefulWidget {
class _AptManagePageState extends State<AptManagePage> class _AptManagePageState extends State<AptManagePage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late MediaQueryData _media; late MediaQueryData _media;
final greyStyle = const TextStyle(color: Colors.grey); final _scrollController = ScrollController();
final scrollController = ScrollController(); final _scrollControllerUpdate = ScrollController();
final scrollControllerUpdate = ScrollController(); final _textController = TextEditingController();
final textController = TextEditingController();
final _aptProvider = locator<AptProvider>(); final _aptProvider = locator<AptProvider>();
late S s; late S _s;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -53,7 +53,7 @@ class _AptManagePageState extends State<AptManagePage>
.servers .servers
.firstWhere((e) => e.info == widget.spi); .firstWhere((e) => e.info == widget.spi);
if (si.client == null) { if (si.client == null) {
showSnackBar(context, Text(s.waitConnection)); showSnackBar(context, Text(_s.waitConnection));
Navigator.of(context).pop(); Navigator.of(context).pop();
return; return;
} }
@@ -61,9 +61,10 @@ class _AptManagePageState extends State<AptManagePage>
_aptProvider.init( _aptProvider.init(
si.client!, si.client!,
si.status.sysVer.dist, si.status.sysVer.dist,
() => scrollController.jumpTo(scrollController.position.maxScrollExtent), () =>
() => scrollControllerUpdate _scrollController.jumpTo(_scrollController.position.maxScrollExtent),
.jumpTo(scrollController.position.maxScrollExtent), () => _scrollControllerUpdate
.jumpTo(_scrollController.position.maxScrollExtent),
onPwdRequest, onPwdRequest,
widget.spi.user, widget.spi.user,
); );
@@ -71,14 +72,14 @@ class _AptManagePageState extends State<AptManagePage>
} }
void onSubmitted() { void onSubmitted() {
if (textController.text == '') { if (_textController.text == '') {
showRoundDialog( showRoundDialog(
context, context,
s.attention, _s.attention,
Text(s.fieldMustNotEmpty), Text(_s.fieldMustNotEmpty),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), child: Text(s.ok)), onPressed: () => Navigator.of(context).pop(), child: Text(_s.ok)),
], ],
); );
return; return;
@@ -92,12 +93,12 @@ class _AptManagePageState extends State<AptManagePage>
context, context,
widget.spi.user, widget.spi.user,
TextField( TextField(
controller: textController, controller: _textController,
keyboardType: TextInputType.visiblePassword, keyboardType: TextInputType.visiblePassword,
obscureText: true, obscureText: true,
onSubmitted: (_) => onSubmitted(), onSubmitted: (_) => onSubmitted(),
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.pwd, labelText: _s.pwd,
), ),
), ),
[ [
@@ -106,16 +107,16 @@ class _AptManagePageState extends State<AptManagePage>
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text(s.cancel)), child: Text(_s.cancel)),
TextButton( TextButton(
onPressed: () => onSubmitted(), onPressed: () => onSubmitted(),
child: Text( child: Text(
s.ok, _s.ok,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
)), )),
], ],
); );
return textController.text.trim(); return _textController.text.trim();
} }
@override @override
@@ -167,7 +168,7 @@ class _AptManagePageState extends State<AptManagePage>
constraints: const BoxConstraints.expand(), constraints: const BoxConstraints.expand(),
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(18), padding: const EdgeInsets.all(18),
controller: scrollControllerUpdate, controller: _scrollControllerUpdate,
child: Text(apt.updateLog!), child: Text(apt.updateLog!),
), ),
), ),
@@ -180,7 +181,7 @@ class _AptManagePageState extends State<AptManagePage>
padding: const EdgeInsets.all(17), padding: const EdgeInsets.all(17),
child: UrlText( child: UrlText(
text: text:
'${s.experimentalFeature}\n${s.reportBugsOnGithubIssue(issueUrl)}', '${_s.experimentalFeature}\n${_s.reportBugsOnGithubIssue(issueUrl)}',
replace: 'Github Issue', replace: 'Github Issue',
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@@ -196,7 +197,7 @@ class _AptManagePageState extends State<AptManagePage>
if (apt.upgradeable!.isEmpty) { if (apt.upgradeable!.isEmpty) {
return ListTile( return ListTile(
title: Text( title: Text(
s.noUpdateAvailable, _s.noUpdateAvailable,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
subtitle: const Text('>_<', textAlign: TextAlign.center), subtitle: const Text('>_<', textAlign: TextAlign.center),
@@ -206,24 +207,24 @@ class _AptManagePageState extends State<AptManagePage>
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ExpansionTile( ExpansionTile(
title: Text(s.foundNUpdate(apt.upgradeable!.length)), title: Text(_s.foundNUpdate(apt.upgradeable!.length)),
subtitle: Text( subtitle: Text(
apt.upgradeable!.map((e) => e.package).join(', '), apt.upgradeable!.map((e) => e.package).join(', '),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: greyStyle, style: grey,
), ),
children: apt.upgradeLog == null children: apt.upgradeLog == null
? [ ? [
TextButton( TextButton(
child: Text(s.updateAll), child: Text(_s.updateAll),
onPressed: () { onPressed: () {
apt.upgrade(); apt.upgrade();
}), }),
SizedBox( SizedBox(
height: _media.size.height * 0.73, height: _media.size.height * 0.73,
child: ListView( child: ListView(
controller: scrollController, controller: _scrollController,
children: apt.upgradeable! children: apt.upgradeable!
.map((e) => _buildUpdateItem(e, apt)) .map((e) => _buildUpdateItem(e, apt))
.toList(), .toList(),
@@ -237,7 +238,7 @@ class _AptManagePageState extends State<AptManagePage>
constraints: const BoxConstraints.expand(), constraints: const BoxConstraints.expand(),
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(18), padding: const EdgeInsets.all(18),
controller: scrollController, controller: _scrollController,
child: Text(apt.upgradeLog!), child: Text(apt.upgradeLog!),
), ),
), ),
@@ -253,7 +254,7 @@ class _AptManagePageState extends State<AptManagePage>
title: Text(info.package), title: Text(info.package),
subtitle: Text( subtitle: Text(
'${info.nowVersion} -> ${info.newVersion}', '${info.nowVersion} -> ${info.newVersion}',
style: greyStyle, style: grey,
), ),
); );
} }

View File

@@ -21,10 +21,10 @@ const backupFormatVersion = 1;
class BackupPage extends StatelessWidget { class BackupPage extends StatelessWidget {
BackupPage({Key? key}) : super(key: key); BackupPage({Key? key}) : super(key: key);
final setting = locator<SettingStore>(); final _setting = locator<SettingStore>();
final server = locator<ServerStore>(); final _server = locator<ServerStore>();
final snippet = locator<SnippetStore>(); final _snippet = locator<SnippetStore>();
final privateKey = locator<PrivateKeyStore>(); final _privateKey = locator<PrivateKeyStore>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -100,12 +100,12 @@ class BackupPage extends StatelessWidget {
Backup( Backup(
backupFormatVersion, backupFormatVersion,
DateTime.now().toString().split('.').first, DateTime.now().toString().split('.').first,
server.fetch(), _server.fetch(),
snippet.fetch(), _snippet.fetch(),
privateKey.fetch(), _privateKey.fetch(),
setting.primaryColor.fetch() ?? Colors.pinkAccent.value, _setting.primaryColor.fetch() ?? Colors.pinkAccent.value,
setting.serverStatusUpdateInterval.fetch() ?? 2, _setting.serverStatusUpdateInterval.fetch() ?? 2,
setting.launchPage.fetch() ?? 0, _setting.launchPage.fetch() ?? 0,
), ),
), ),
); );
@@ -186,18 +186,18 @@ class BackupPage extends StatelessWidget {
TextButton( TextButton(
onPressed: () async { onPressed: () async {
for (final s in backup.snippets) { for (final s in backup.snippets) {
snippet.put(s); _snippet.put(s);
} }
for (final s in backup.spis) { for (final s in backup.spis) {
server.put(s); _server.put(s);
} }
for (final s in backup.keys) { for (final s in backup.keys) {
privateKey.put(s); _privateKey.put(s);
} }
setting.primaryColor.put(backup.primaryColor); _setting.primaryColor.put(backup.primaryColor);
setting.serverStatusUpdateInterval _setting.serverStatusUpdateInterval
.put(backup.serverStatusUpdateInterval); .put(backup.serverStatusUpdateInterval);
setting.launchPage.put(backup.launchPage); _setting.launchPage.put(backup.launchPage);
Navigator.of(context).pop(); Navigator.of(context).pop();
showSnackBar(context, Text(s.restoreSuccess)); showSnackBar(context, Text(s.restoreSuccess));
}, },

View File

@@ -21,7 +21,7 @@ class _ConvertPageState extends State<ConvertPage>
late TextEditingController _textEditingControllerResult; late TextEditingController _textEditingControllerResult;
late MediaQueryData _media; late MediaQueryData _media;
late ThemeData _theme; late ThemeData _theme;
late S s; late S _s;
int _typeOptionIndex = 0; int _typeOptionIndex = 0;
@@ -37,7 +37,7 @@ class _ConvertPageState extends State<ConvertPage>
super.didChangeDependencies(); super.didChangeDependencies();
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
_theme = Theme.of(context); _theme = Theme.of(context);
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -65,7 +65,7 @@ class _ConvertPageState extends State<ConvertPage>
showSnackBar(context, Text('Error: \n$e')); showSnackBar(context, Text('Error: \n$e'));
} }
}, },
tooltip: s.convert, tooltip: _s.convert,
heroTag: 'convert fab', heroTag: 'convert fab',
child: const Icon(Icons.send), child: const Icon(Icons.send),
), ),
@@ -84,7 +84,7 @@ class _ConvertPageState extends State<ConvertPage>
case 3: case 3:
return Uri.decodeFull(text); return Uri.decodeFull(text);
default: default:
return s.unkownConvertMode; return _s.unkownConvertMode;
} }
} }
@@ -96,8 +96,8 @@ class _ConvertPageState extends State<ConvertPage>
} }
Widget _buildTypeOption() { Widget _buildTypeOption() {
final decode = s.decode; final decode = _s.decode;
final encode = s.encode; final encode = _s.encode;
final List<String> typeOption = [ final List<String> typeOption = [
'Base64 $decode', 'Base64 $decode',
'Base64 $encode', 'Base64 $encode',
@@ -113,7 +113,7 @@ class _ConvertPageState extends State<ConvertPage>
TextButton( TextButton(
style: ButtonStyle( style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(primaryColor)), foregroundColor: MaterialStateProperty.all(primaryColor)),
child: Icon(Icons.change_circle, semanticLabel: s.upsideDown), child: Icon(Icons.change_circle, semanticLabel: _s.upsideDown),
onPressed: () { onPressed: () {
final temp = _textEditingController.text; final temp = _textEditingController.text;
_textEditingController.text = _textEditingControllerResult.text; _textEditingController.text = _textEditingControllerResult.text;
@@ -124,7 +124,7 @@ class _ConvertPageState extends State<ConvertPage>
style: ButtonStyle( style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(primaryColor), foregroundColor: MaterialStateProperty.all(primaryColor),
), ),
child: Icon(Icons.copy, semanticLabel: s.copy), child: Icon(Icons.copy, semanticLabel: _s.copy),
onPressed: () => Clipboard.setData( onPressed: () => Clipboard.setData(
ClipboardData( ClipboardData(
text: _textEditingControllerResult.text == '' text: _textEditingControllerResult.text == ''
@@ -150,7 +150,7 @@ class _ConvertPageState extends State<ConvertPage>
color: primaryColor), color: primaryColor),
), ),
Text( Text(
s.currentMode, _s.currentMode,
textScaleFactor: 1.0, textScaleFactor: 1.0,
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: const TextStyle(fontSize: 9.0, color: Colors.grey), style: const TextStyle(fontSize: 9.0, color: Colors.grey),

View File

@@ -7,6 +7,7 @@ import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/provider/docker.dart'; import 'package:toolbox/data/provider/docker.dart';
import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/res/error.dart'; import 'package:toolbox/data/res/error.dart';
import 'package:toolbox/data/res/font_style.dart';
import 'package:toolbox/data/res/url.dart'; import 'package:toolbox/data/res/url.dart';
import 'package:toolbox/data/store/docker.dart'; import 'package:toolbox/data/store/docker.dart';
import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/generated/l10n.dart';
@@ -26,9 +27,8 @@ class DockerManagePage extends StatefulWidget {
class _DockerManagePageState extends State<DockerManagePage> { class _DockerManagePageState extends State<DockerManagePage> {
final _docker = locator<DockerProvider>(); final _docker = locator<DockerProvider>();
final greyTextStyle = const TextStyle(color: Colors.grey); final _textController = TextEditingController();
final textController = TextEditingController(); late S _s;
late S s;
@override @override
void dispose() { void dispose() {
@@ -39,7 +39,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -50,7 +50,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
.firstWhere((element) => element.info == widget.spi) .firstWhere((element) => element.info == widget.spi)
.client; .client;
if (client == null) { if (client == null) {
showSnackBar(context, Text(s.noClient)); showSnackBar(context, Text(_s.noClient));
Navigator.of(context).pop(); Navigator.of(context).pop();
return; return;
} }
@@ -90,14 +90,14 @@ class _DockerManagePageState extends State<DockerManagePage> {
final argsCtrl = TextEditingController(); final argsCtrl = TextEditingController();
await showRoundDialog( await showRoundDialog(
context, context,
s.newContainer, _s.newContainer,
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
TextField( TextField(
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.dockerImage, hintText: 'ubuntu:22.10'), labelText: _s.dockerImage, hintText: 'ubuntu:22.10'),
controller: imageCtrl, controller: imageCtrl,
autocorrect: false, autocorrect: false,
), ),
@@ -105,14 +105,15 @@ class _DockerManagePageState extends State<DockerManagePage> {
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
controller: nameCtrl, controller: nameCtrl,
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.dockerContainerName, hintText: 'ubuntu22'), labelText: _s.dockerContainerName, hintText: 'ubuntu22'),
autocorrect: false, autocorrect: false,
), ),
TextField( TextField(
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
controller: argsCtrl, controller: argsCtrl,
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.extraArgs, hintText: '-p 2222:22 -v ~/.xxx/:/xxx'), labelText: _s.extraArgs,
hintText: '-p 2222:22 -v ~/.xxx/:/xxx'),
autocorrect: false, autocorrect: false,
), ),
], ],
@@ -120,7 +121,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
@@ -133,7 +134,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
), ),
); );
}, },
child: Text(s.ok), child: Text(_s.ok),
) )
], ],
); );
@@ -142,22 +143,22 @@ class _DockerManagePageState extends State<DockerManagePage> {
Future<void> _showAddCmdPreview(String cmd) async { Future<void> _showAddCmdPreview(String cmd) async {
await showRoundDialog( await showRoundDialog(
context, context,
s.preview, _s.preview,
Text(cmd), Text(cmd),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
Navigator.of(context).pop(); Navigator.of(context).pop();
final result = await _docker.run(cmd); final result = await _docker.run(cmd);
if (result != null) { if (result != null) {
showSnackBar(context, Text(getErrMsg(result) ?? s.unknownError)); showSnackBar(context, Text(getErrMsg(result) ?? _s.unknownError));
} }
}, },
child: Text(s.run), child: Text(_s.run),
) )
], ],
); );
@@ -184,10 +185,10 @@ class _DockerManagePageState extends State<DockerManagePage> {
} }
void onSubmitted() { void onSubmitted() {
if (textController.text == '') { if (_textController.text == '') {
showRoundDialog(context, s.attention, Text(s.fieldMustNotEmpty), [ showRoundDialog(context, _s.attention, Text(_s.fieldMustNotEmpty), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), child: Text(s.ok)), onPressed: () => Navigator.of(context).pop(), child: Text(_s.ok)),
]); ]);
return; return;
} }
@@ -200,12 +201,12 @@ class _DockerManagePageState extends State<DockerManagePage> {
context, context,
widget.spi.user, widget.spi.user,
TextField( TextField(
controller: textController, controller: _textController,
keyboardType: TextInputType.visiblePassword, keyboardType: TextInputType.visiblePassword,
obscureText: true, obscureText: true,
onSubmitted: (_) => onSubmitted(), onSubmitted: (_) => onSubmitted(),
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.pwd, labelText: _s.pwd,
), ),
), ),
[ [
@@ -214,18 +215,18 @@ class _DockerManagePageState extends State<DockerManagePage> {
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text(s.cancel), child: Text(_s.cancel),
), ),
TextButton( TextButton(
onPressed: () => onSubmitted(), onPressed: () => onSubmitted(),
child: Text( child: Text(
s.ok, _s.ok,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
), ),
], ],
); );
return textController.text.trim(); return _textController.text.trim();
} }
Widget _buildMain(DockerProvider docker) { Widget _buildMain(DockerProvider docker) {
@@ -260,7 +261,8 @@ class _DockerManagePageState extends State<DockerManagePage> {
padding: const EdgeInsets.all(7), padding: const EdgeInsets.all(7),
children: [ children: [
_buildLoading(docker), _buildLoading(docker),
_buildVersion(docker.edition ?? s.unknown, docker.version ?? s.unknown), _buildVersion(
docker.edition ?? _s.unknown, docker.version ?? _s.unknown),
_buildPsItems(running, docker), _buildPsItems(running, docker),
_buildImages(docker), _buildImages(docker),
_buildEditHost(running, docker), _buildEditHost(running, docker),
@@ -273,10 +275,10 @@ class _DockerManagePageState extends State<DockerManagePage> {
return const SizedBox(); return const SizedBox();
} }
return ExpansionTile( return ExpansionTile(
title: Text(s.imagesList), title: Text(_s.imagesList),
subtitle: Text( subtitle: Text(
s.dockerImagesFmt(docker.images!.length), _s.dockerImagesFmt(docker.images!.length),
style: greyTextStyle, style: grey,
), ),
children: docker.images! children: docker.images!
.map( .map(
@@ -289,7 +291,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
final result = await _docker.run('docker rmi ${e.id} -f'); final result = await _docker.run('docker rmi ${e.id} -f');
if (result != null) { if (result != null) {
showSnackBar( showSnackBar(
context, Text(getErrMsg(result) ?? s.unknownError)); context, Text(getErrMsg(result) ?? _s.unknownError));
} }
}, },
), ),
@@ -322,12 +324,12 @@ class _DockerManagePageState extends State<DockerManagePage> {
child: Column( child: Column(
children: [ children: [
Text( Text(
s.dockerEmptyRunningItems, _s.dockerEmptyRunningItems,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
TextButton( TextButton(
onPressed: () => _showEditHostDialog(docker), onPressed: () => _showEditHostDialog(docker),
child: Text(s.dockerEditHost), child: Text(_s.dockerEditHost),
) )
], ],
), ),
@@ -337,7 +339,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
Future<void> _showEditHostDialog(DockerProvider docker) async { Future<void> _showEditHostDialog(DockerProvider docker) async {
await showRoundDialog( await showRoundDialog(
context, context,
s.dockerEditHost, _s.dockerEditHost,
TextField( TextField(
maxLines: 1, maxLines: 1,
autocorrect: false, autocorrect: false,
@@ -352,7 +354,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
], ],
); );
@@ -362,16 +364,16 @@ class _DockerManagePageState extends State<DockerManagePage> {
var errStr = ''; var errStr = '';
switch (err.type) { switch (err.type) {
case DockerErrType.noClient: case DockerErrType.noClient:
errStr = s.noClient; errStr = _s.noClient;
break; break;
case DockerErrType.notInstalled: case DockerErrType.notInstalled:
errStr = s.dockerNotInstalled; errStr = _s.dockerNotInstalled;
break; break;
case DockerErrType.invalidVersion: case DockerErrType.invalidVersion:
errStr = s.invalidVersion; errStr = _s.invalidVersion;
break; break;
default: default:
errStr = err.message ?? s.unknown; errStr = err.message ?? _s.unknown;
} }
return Text(errStr); return Text(errStr);
} }
@@ -380,18 +382,18 @@ class _DockerManagePageState extends State<DockerManagePage> {
switch (err.type) { switch (err.type) {
case DockerErrType.notInstalled: case DockerErrType.notInstalled:
return UrlText( return UrlText(
text: s.installDockerWithUrl, text: _s.installDockerWithUrl,
replace: s.install, replace: _s.install,
); );
case DockerErrType.noClient: case DockerErrType.noClient:
return Text(s.waitConnection); return Text(_s.waitConnection);
case DockerErrType.invalidVersion: case DockerErrType.invalidVersion:
return UrlText( return UrlText(
text: s.invalidVersionHelp(issueUrl), text: _s.invalidVersionHelp(issueUrl),
replace: 'Github', replace: 'Github',
); );
default: default:
return Text(s.unknownError); return Text(_s.unknownError);
} }
} }
@@ -407,8 +409,8 @@ class _DockerManagePageState extends State<DockerManagePage> {
Widget _buildPsItems(List<DockerPsItem> running, DockerProvider docker) { Widget _buildPsItems(List<DockerPsItem> running, DockerProvider docker) {
return ExpansionTile( return ExpansionTile(
title: Text(s.containerStatus), title: Text(_s.containerStatus),
subtitle: Text(_buildSubtitle(running), style: greyTextStyle), subtitle: Text(_buildSubtitle(running), style: grey),
children: running.map( children: running.map(
(item) { (item) {
return ListTile( return ListTile(
@@ -437,7 +439,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
], ],
onSelected: (value) { onSelected: (value) {
if (busy) { if (busy) {
showSnackBar(context, Text(s.isBusy)); showSnackBar(context, Text(_s.isBusy));
return; return;
} }
final item = value as DropdownBtnItem; final item = value as DropdownBtnItem;
@@ -460,8 +462,8 @@ class _DockerManagePageState extends State<DockerManagePage> {
final runningCount = running.where((element) => element.running).length; final runningCount = running.where((element) => element.running).length;
final stoped = running.length - runningCount; final stoped = running.length - runningCount;
if (stoped == 0) { if (stoped == 0) {
return s.dockerStatusRunningFmt(runningCount); return _s.dockerStatusRunningFmt(runningCount);
} }
return s.dockerStatusRunningAndStoppedFmt(runningCount, stoped); return _s.dockerStatusRunningAndStoppedFmt(runningCount, stoped);
} }
} }

View File

@@ -45,7 +45,7 @@ class _MyHomePageState extends State<MyHomePage>
late final PageController _pageController; late final PageController _pageController;
late int _selectIndex; late int _selectIndex;
late double _width; late double _width;
late S s; late S _s;
@override @override
void initState() { void initState() {
@@ -59,7 +59,7 @@ class _MyHomePageState extends State<MyHomePage>
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
_width = MediaQuery.of(context).size.width; _width = MediaQuery.of(context).size.width;
} }
@@ -84,20 +84,6 @@ class _MyHomePageState extends State<MyHomePage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
return WillPopScope(
child: _buildMain(context),
onWillPop: () {
final scaffold = Scaffold.of(context);
if (scaffold.isDrawerOpen) {
scaffold.closeDrawer();
return Future.value(false);
}
return Future.value(true);
},
);
}
Widget _buildMain(BuildContext context) {
return Scaffold( return Scaffold(
drawer: _buildDrawer(), drawer: _buildDrawer(),
appBar: AppBar( appBar: AppBar(
@@ -105,7 +91,7 @@ class _MyHomePageState extends State<MyHomePage>
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.developer_mode, size: 23), icon: const Icon(Icons.developer_mode, size: 23),
tooltip: s.debug, tooltip: _s.debug,
onPressed: () => onPressed: () =>
AppRoute(const DebugPage(), 'Debug Page').go(context), AppRoute(const DebugPage(), 'Debug Page').go(context),
), ),
@@ -126,7 +112,6 @@ class _MyHomePageState extends State<MyHomePage>
} }
Widget _buildItem(int idx, NavigationItem item, bool isSelected) { Widget _buildItem(int idx, NavigationItem item, bool isSelected) {
bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
final width = _width / tabItems.length; final width = _width / tabItems.length;
return AnimatedContainer( return AnimatedContainer(
duration: const Duration(milliseconds: 377), duration: const Duration(milliseconds: 377),
@@ -135,7 +120,7 @@ class _MyHomePageState extends State<MyHomePage>
width: isSelected ? width : width - 17, width: isSelected ? width : width - 17,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected color: isSelected
? isDarkMode ? isDarkMode(context)
? Colors.white12 ? Colors.white12
: Colors.black.withOpacity(0.07) : Colors.black.withOpacity(0.07)
: Colors.transparent, : Colors.transparent,
@@ -195,57 +180,57 @@ class _MyHomePageState extends State<MyHomePage>
children: [ children: [
ListTile( ListTile(
leading: const Icon(Icons.settings), leading: const Icon(Icons.settings),
title: Text(s.setting), title: Text(_s.setting),
onTap: () => onTap: () =>
AppRoute(const SettingPage(), 'Setting').go(context), AppRoute(const SettingPage(), 'Setting').go(context),
), ),
ListTile( ListTile(
leading: const Icon(Icons.vpn_key), leading: const Icon(Icons.vpn_key),
title: Text(s.privateKey), title: Text(_s.privateKey),
onTap: () => AppRoute( onTap: () => AppRoute(
const StoredPrivateKeysPage(), 'private key list') const StoredPrivateKeysPage(), 'private key list')
.go(context), .go(context),
), ),
ListTile( ListTile(
leading: const Icon(Icons.download), leading: const Icon(Icons.download),
title: Text(s.download), title: Text(_s.download),
onTap: () => onTap: () =>
AppRoute(const SFTPDownloadedPage(), 'snippet list') AppRoute(const SFTPDownloadedPage(), 'snippet list')
.go(context), .go(context),
), ),
ListTile( ListTile(
leading: const Icon(Icons.import_export), leading: const Icon(Icons.import_export),
title: Text(s.backup), title: Text(_s.backup),
onTap: () => onTap: () =>
AppRoute(BackupPage(), 'backup page').go(context), AppRoute(BackupPage(), 'backup page').go(context),
), ),
ListTile( ListTile(
leading: const Icon(Icons.info), leading: const Icon(Icons.info),
title: Text(s.feedback), title: Text(_s.feedback),
onTap: () => showRoundDialog( onTap: () => showRoundDialog(
context, context,
s.feedback, _s.feedback,
Text(s.feedbackOnGithub), Text(_s.feedbackOnGithub),
[ [
TextButton( TextButton(
onPressed: () => Clipboard.setData( onPressed: () => Clipboard.setData(
const ClipboardData(text: issueUrl)), const ClipboardData(text: issueUrl)),
child: Text(s.copy), child: Text(_s.copy),
), ),
TextButton( TextButton(
onPressed: () => openUrl(issueUrl), onPressed: () => openUrl(issueUrl),
child: Text(s.feedback), child: Text(_s.feedback),
), ),
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.close), child: Text(_s.close),
) )
], ],
), ),
), ),
ListTile( ListTile(
leading: const Icon(Icons.snippet_folder), leading: const Icon(Icons.snippet_folder),
title: Text(s.snippet), title: Text(_s.snippet),
onTap: () => AppRoute(const SnippetListPage(), 'snippet list') onTap: () => AppRoute(const SnippetListPage(), 'snippet list')
.go(context), .go(context),
), ),
@@ -256,9 +241,10 @@ class _MyHomePageState extends State<MyHomePage>
applicationIcon: _buildIcon(), applicationIcon: _buildIcon(),
aboutBoxChildren: [ aboutBoxChildren: [
UrlText( UrlText(
text: s.madeWithLove(myGithub), replace: 'lollipopkit'), text: _s.madeWithLove(myGithub),
replace: 'lollipopkit'),
UrlText( UrlText(
text: s.aboutThanks, text: _s.aboutThanks,
), ),
const UrlText( const UrlText(
text: rainSunMeGithub, text: rainSunMeGithub,
@@ -269,7 +255,7 @@ class _MyHomePageState extends State<MyHomePage>
replace: 'fecture', replace: 'fecture',
) )
], ],
child: Text(s.license), child: Text(_s.license),
) )
], ],
), ),

View File

@@ -4,6 +4,7 @@ import 'package:toolbox/core/utils.dart';
import 'package:toolbox/data/model/server/ping_result.dart'; import 'package:toolbox/data/model/server/ping_result.dart';
import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/res/color.dart'; import 'package:toolbox/data/res/color.dart';
import 'package:toolbox/data/res/font_style.dart';
import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/generated/l10n.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/input_field.dart';
@@ -29,9 +30,6 @@ class _PingPageState extends State<PingPage>
final List<PingResult> _results = []; final List<PingResult> _results = [];
final _serverProvider = locator<ServerProvider>(); final _serverProvider = locator<ServerProvider>();
late S s; late S s;
static const summaryTextStyle = TextStyle(
fontSize: 12,
);
@override @override
void initState() { void initState() {
@@ -103,7 +101,7 @@ class _PingPageState extends State<PingPage>
), ),
subtitle: Text( subtitle: Text(
_buildPingSummary(result, unknown, ms), _buildPingSummary(result, unknown, ms),
style: summaryTextStyle, style: textSize11,
), ),
trailing: Text( trailing: Text(
'${s.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? s.unknown} $ms', '${s.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? s.unknown} $ms',

View File

@@ -21,42 +21,42 @@ class PrivateKeyEditPage extends StatefulWidget {
class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
with AfterLayoutMixin { with AfterLayoutMixin {
final nameController = TextEditingController(); final _nameController = TextEditingController();
final keyController = TextEditingController(); final _keyController = TextEditingController();
final pwdController = TextEditingController(); final _pwdController = TextEditingController();
final nameNode = FocusNode(); final _nameNode = FocusNode();
final keyNode = FocusNode(); final _keyNode = FocusNode();
final pwdNode = FocusNode(); final _pwdNode = FocusNode();
late FocusScopeNode focusScope;
late FocusScopeNode _focusScope;
late PrivateKeyProvider _provider; late PrivateKeyProvider _provider;
late Widget loading; late S _s;
late S s;
Widget _loading = const SizedBox();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_provider = locator<PrivateKeyProvider>(); _provider = locator<PrivateKeyProvider>();
loading = const SizedBox(); _loading = const SizedBox();
} }
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
focusScope = FocusScope.of(context); _focusScope = FocusScope.of(context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.edit, style: textSize18), title: Text(_s.edit, style: textSize18),
actions: [ actions: [
widget.info != null widget.info != null
? IconButton( ? IconButton(
tooltip: s.delete, tooltip: _s.delete,
onPressed: () { onPressed: () {
_provider.delInfo(widget.info!); _provider.delInfo(widget.info!);
Navigator.of(context).pop(); Navigator.of(context).pop();
@@ -69,48 +69,48 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
padding: const EdgeInsets.all(13), padding: const EdgeInsets.all(13),
children: [ children: [
TextField( TextField(
controller: nameController, controller: _nameController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
focusNode: nameNode, focusNode: _nameNode,
onSubmitted: (_) => focusScope.requestFocus(keyNode), onSubmitted: (_) => _focusScope.requestFocus(_keyNode),
decoration: buildDecoration(s.name, icon: Icons.info), decoration: buildDecoration(_s.name, icon: Icons.info),
), ),
TextField( TextField(
controller: keyController, controller: _keyController,
autocorrect: false, autocorrect: false,
minLines: 3, minLines: 3,
maxLines: 10, maxLines: 10,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
focusNode: keyNode, focusNode: _keyNode,
onSubmitted: (_) => focusScope.requestFocus(pwdNode), onSubmitted: (_) => _focusScope.requestFocus(_pwdNode),
enableSuggestions: false, enableSuggestions: false,
decoration: buildDecoration(s.privateKey, icon: Icons.vpn_key), decoration: buildDecoration(_s.privateKey, icon: Icons.vpn_key),
), ),
TextField( TextField(
controller: pwdController, controller: _pwdController,
autocorrect: false, autocorrect: false,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
focusNode: pwdNode, focusNode: _pwdNode,
obscureText: true, obscureText: true,
decoration: buildDecoration(s.pwd, icon: Icons.password), decoration: buildDecoration(_s.pwd, icon: Icons.password),
), ),
SizedBox(height: MediaQuery.of(context).size.height * 0.1), SizedBox(height: MediaQuery.of(context).size.height * 0.1),
loading _loading
], ],
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
tooltip: s.save, tooltip: _s.save,
onPressed: () async { onPressed: () async {
final name = nameController.text; final name = _nameController.text;
final key = keyController.text.trim(); final key = _keyController.text.trim();
final pwd = pwdController.text; final pwd = _pwdController.text;
if (name.isEmpty || key.isEmpty) { if (name.isEmpty || key.isEmpty) {
showSnackBar(context, Text(s.fieldMustNotEmpty)); showSnackBar(context, Text(_s.fieldMustNotEmpty));
return; return;
} }
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
setState(() { setState(() {
loading = const SizedBox( _loading = const SizedBox(
height: 50, height: 50,
child: Center( child: Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
@@ -126,7 +126,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
haveErr = true; haveErr = true;
} finally { } finally {
setState(() { setState(() {
loading = const SizedBox(); _loading = const SizedBox();
}); });
} }
if (haveErr) return; if (haveErr) return;
@@ -145,9 +145,9 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
@override @override
void afterFirstLayout(BuildContext context) { void afterFirstLayout(BuildContext context) {
if (widget.info != null) { if (widget.info != null) {
nameController.text = widget.info!.id; _nameController.text = widget.info!.id;
keyController.text = widget.info!.privateKey; _keyController.text = widget.info!.privateKey;
pwdController.text = widget.info!.password; _pwdController.text = widget.info!.password;
} }
} }
} }

View File

@@ -17,20 +17,19 @@ class StoredPrivateKeysPage extends StatefulWidget {
} }
class _PrivateKeyListState extends State<StoredPrivateKeysPage> { class _PrivateKeyListState extends State<StoredPrivateKeysPage> {
final _textStyle = TextStyle(color: primaryColor); late S _s;
late S s;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.privateKey, style: textSize18), title: Text(_s.privateKey, style: textSize18),
), ),
body: Consumer<PrivateKeyProvider>( body: Consumer<PrivateKeyProvider>(
builder: (_, key, __) { builder: (_, key, __) {
@@ -55,17 +54,14 @@ class _PrivateKeyListState extends State<StoredPrivateKeysPage> {
PrivateKeyEditPage(info: key.infos[idx]), PrivateKeyEditPage(info: key.infos[idx]),
'private key edit page') 'private key edit page')
.go(context), .go(context),
child: Text( child: Text(_s.edit),
s.edit,
style: _textStyle,
),
) )
], ],
), ),
)); ));
}) })
: Center( : Center(
child: Text(s.noSavedPrivateKey), child: Text(_s.noSavedPrivateKey),
); );
}, },
), ),

View File

@@ -24,13 +24,13 @@ class ServerDetailPage extends StatefulWidget {
class _ServerDetailPageState extends State<ServerDetailPage> class _ServerDetailPageState extends State<ServerDetailPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late MediaQueryData _media; late MediaQueryData _media;
late S s; late S _s;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -315,7 +315,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
if (ns.devices.isEmpty) { if (ns.devices.isEmpty) {
children.add(Center( children.add(Center(
child: Text( child: Text(
s.noInterface, _s.noInterface,
style: const TextStyle(color: Colors.grey, fontSize: 13), style: const TextStyle(color: Colors.grey, fontSize: 13),
), ),
)); ));

View File

@@ -25,25 +25,21 @@ class ServerEditPage extends StatefulWidget {
} }
class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin { class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
final nameController = TextEditingController(); final _nameController = TextEditingController();
final ipController = TextEditingController(); final _ipController = TextEditingController();
final portController = TextEditingController(); final _portController = TextEditingController();
final usernameController = TextEditingController(); final _usernameController = TextEditingController();
final passwordController = TextEditingController(); final _passwordController = TextEditingController();
final keyController = TextEditingController(); final _nameFocus = FocusNode();
final nameFocus = FocusNode(); final _ipFocus = FocusNode();
final ipFocus = FocusNode(); final _portFocus = FocusNode();
final portFocus = FocusNode(); final _usernameFocus = FocusNode();
final usernameFocus = FocusNode();
late FocusScopeNode focusScope;
late FocusScopeNode _focusScope;
late ServerProvider _serverProvider; late ServerProvider _serverProvider;
late S _s;
late S s;
bool usePublicKey = false; bool usePublicKey = false;
int? _pubKeyIndex; int? _pubKeyIndex;
PrivateKeyInfo? _keyInfo; PrivateKeyInfo? _keyInfo;
@@ -56,23 +52,23 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
focusScope = FocusScope.of(context); _focusScope = FocusScope.of(context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.edit, style: textSize18), title: Text(_s.edit, style: textSize18),
actions: [ actions: [
widget.spi != null widget.spi != null
? IconButton( ? IconButton(
onPressed: () { onPressed: () {
showRoundDialog( showRoundDialog(
context, context,
s.attention, _s.attention,
Text(s.sureToDeleteServer(widget.spi!.name)), Text(_s.sureToDeleteServer(widget.spi!.name)),
[ [
TextButton( TextButton(
onPressed: () { onPressed: () {
@@ -81,13 +77,13 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text( child: Text(
s.ok, _s.ok,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
), ),
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
) )
], ],
); );
@@ -104,44 +100,44 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
TextField( TextField(
controller: nameController, controller: _nameController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
focusNode: nameFocus, focusNode: _nameFocus,
onSubmitted: (_) => focusScope.requestFocus(ipFocus), onSubmitted: (_) => _focusScope.requestFocus(_ipFocus),
decoration: buildDecoration(s.name, decoration: buildDecoration(_s.name,
icon: Icons.info, hint: s.exampleName), icon: Icons.info, hint: _s.exampleName),
), ),
TextField( TextField(
controller: ipController, controller: _ipController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
onSubmitted: (_) => focusScope.requestFocus(portFocus), onSubmitted: (_) => _focusScope.requestFocus(_portFocus),
focusNode: ipFocus, focusNode: _ipFocus,
autocorrect: false, autocorrect: false,
enableSuggestions: false, enableSuggestions: false,
decoration: buildDecoration(s.host, decoration: buildDecoration(_s.host,
icon: Icons.storage, hint: 'example.com'), icon: Icons.storage, hint: 'example.com'),
), ),
TextField( TextField(
controller: portController, controller: _portController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
focusNode: portFocus, focusNode: _portFocus,
onSubmitted: (_) => focusScope.requestFocus(usernameFocus), onSubmitted: (_) => _focusScope.requestFocus(_usernameFocus),
decoration: buildDecoration(s.port, decoration: buildDecoration(_s.port,
icon: Icons.format_list_numbered, hint: '22'), icon: Icons.format_list_numbered, hint: '22'),
), ),
TextField( TextField(
controller: usernameController, controller: _usernameController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
focusNode: usernameFocus, focusNode: _usernameFocus,
autocorrect: false, autocorrect: false,
enableSuggestions: false, enableSuggestions: false,
decoration: buildDecoration(s.user, decoration: buildDecoration(_s.user,
icon: Icons.account_box, hint: 'root'), icon: Icons.account_box, hint: 'root'),
), ),
const SizedBox(height: 7), const SizedBox(height: 7),
Row( Row(
children: [ children: [
Text(s.keyAuth), Text(_s.keyAuth),
Switch( Switch(
value: usePublicKey, value: usePublicKey,
onChanged: (val) => setState(() => usePublicKey = val)), onChanged: (val) => setState(() => usePublicKey = val)),
@@ -149,11 +145,11 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
), ),
!usePublicKey !usePublicKey
? TextField( ? TextField(
controller: passwordController, controller: _passwordController,
obscureText: true, obscureText: true,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
decoration: buildDecoration(s.pwd, decoration: buildDecoration(_s.pwd,
icon: Icons.password, hint: s.pwd), icon: Icons.password, hint: _s.pwd),
onSubmitted: (_) => {}, onSubmitted: (_) => {},
) )
: const SizedBox(), : const SizedBox(),
@@ -175,7 +171,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
.toList(); .toList();
tiles.add( tiles.add(
ListTile( ListTile(
title: Text(s.addPrivateKey), title: Text(_s.addPrivateKey),
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
trailing: IconButton( trailing: IconButton(
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
@@ -192,7 +188,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
tilePadding: EdgeInsets.zero, tilePadding: EdgeInsets.zero,
childrenPadding: EdgeInsets.zero, childrenPadding: EdgeInsets.zero,
title: Text( title: Text(
s.choosePrivateKey, _s.choosePrivateKey,
style: const TextStyle(fontSize: 14), style: const TextStyle(fontSize: 14),
), ),
children: tiles, children: tiles,
@@ -206,22 +202,22 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
child: const Icon(Icons.send), child: const Icon(Icons.send),
onPressed: () async { onPressed: () async {
if (ipController.text == '') { if (_ipController.text == '') {
showSnackBar(context, Text(s.plzEnterHost)); showSnackBar(context, Text(_s.plzEnterHost));
return; return;
} }
if (!usePublicKey && passwordController.text == '') { if (!usePublicKey && _passwordController.text == '') {
final cancel = await showRoundDialog<bool>( final cancel = await showRoundDialog<bool>(
context, context,
s.attention, _s.attention,
Text(s.sureNoPwd), Text(_s.sureNoPwd),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(false), onPressed: () => Navigator.of(context).pop(false),
child: Text(s.ok)), child: Text(_s.ok)),
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(true), onPressed: () => Navigator.of(context).pop(true),
child: Text(s.cancel)) child: Text(_s.cancel))
], ],
barrierDismiss: false, barrierDismiss: false,
); );
@@ -230,26 +226,26 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
} }
} }
if (usePublicKey && _pubKeyIndex == -1) { if (usePublicKey && _pubKeyIndex == -1) {
showSnackBar(context, Text(s.plzSelectKey)); showSnackBar(context, Text(_s.plzSelectKey));
return; return;
} }
if (usernameController.text == '') { if (_usernameController.text == '') {
usernameController.text = 'root'; _usernameController.text = 'root';
} }
if (portController.text == '') { if (_portController.text == '') {
portController.text = '22'; _portController.text = '22';
} }
if (widget.spi != null && widget.spi!.pubKeyId != null) { if (widget.spi != null && widget.spi!.pubKeyId != null) {
_keyInfo ??= locator<PrivateKeyStore>().get(widget.spi!.pubKeyId!); _keyInfo ??= locator<PrivateKeyStore>().get(widget.spi!.pubKeyId!);
} }
final authorization = passwordController.text; final authorization = _passwordController.text;
final spi = ServerPrivateInfo( final spi = ServerPrivateInfo(
name: nameController.text, name: _nameController.text,
ip: ipController.text, ip: _ipController.text,
port: int.parse(portController.text), port: int.parse(_portController.text),
user: usernameController.text, user: _usernameController.text,
pwd: authorization, pwd: authorization,
pubKeyId: usePublicKey ? _keyInfo!.id : null, pubKeyId: usePublicKey ? _keyInfo!.id : null,
); );
@@ -282,12 +278,12 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
@override @override
void afterFirstLayout(BuildContext context) { void afterFirstLayout(BuildContext context) {
if (widget.spi != null) { if (widget.spi != null) {
nameController.text = widget.spi?.name ?? ''; _nameController.text = widget.spi?.name ?? '';
ipController.text = widget.spi?.ip ?? ''; _ipController.text = widget.spi?.ip ?? '';
portController.text = (widget.spi?.port ?? 22).toString(); _portController.text = (widget.spi?.port ?? 22).toString();
usernameController.text = widget.spi?.user ?? ''; _usernameController.text = widget.spi?.user ?? '';
if (widget.spi?.pubKeyId == null) { if (widget.spi?.pubKeyId == null) {
passwordController.text = widget.spi?.pwd ?? ''; _passwordController.text = widget.spi?.pwd ?? '';
} else { } else {
usePublicKey = true; usePublicKey = true;
} }

View File

@@ -33,9 +33,8 @@ class _ServerPageState extends State<ServerPage>
late MediaQueryData _media; late MediaQueryData _media;
late ThemeData _theme; late ThemeData _theme;
late Color _primaryColor; late Color _primaryColor;
late ServerProvider _serverProvider; late ServerProvider _serverProvider;
late S s; late S _s;
@override @override
void initState() { void initState() {
@@ -49,7 +48,7 @@ class _ServerPageState extends State<ServerPage>
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
_theme = Theme.of(context); _theme = Theme.of(context);
_primaryColor = primaryColor; _primaryColor = primaryColor;
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -60,7 +59,7 @@ class _ServerPageState extends State<ServerPage>
if (pro.servers.isEmpty) { if (pro.servers.isEmpty) {
return Center( return Center(
child: Text( child: Text(
s.serverTabEmpty, _s.serverTabEmpty,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
); );
@@ -87,7 +86,7 @@ class _ServerPageState extends State<ServerPage>
onPressed: () => onPressed: () =>
AppRoute(const ServerEditPage(), 'Add server info page') AppRoute(const ServerEditPage(), 'Add server info page')
.go(context), .go(context),
tooltip: s.addAServer, tooltip: _s.addAServer,
heroTag: 'server page fab', heroTag: 'server page fab',
child: const Icon(Icons.add), child: const Icon(Icons.add),
), ),
@@ -155,8 +154,8 @@ class _ServerPageState extends State<ServerPage>
hasError hasError
? GestureDetector( ? GestureDetector(
onTap: () => showRoundDialog( onTap: () => showRoundDialog(
context, s.error, Text(ss.failedInfo ?? ''), []), context, _s.error, Text(ss.failedInfo ?? ''), []),
child: Text(s.clickSee, style: style)) child: Text(_s.clickSee, style: style))
: Text(topRightStr, style: style, textScaleFactor: 1.0), : Text(topRightStr, style: style, textScaleFactor: 1.0),
_buildMoreBtn(spi), _buildMoreBtn(spi),
], ],
@@ -248,11 +247,11 @@ class _ServerPageState extends State<ServerPage>
String? failedInfo) { String? failedInfo) {
switch (cs) { switch (cs) {
case ServerConnectionState.disconnected: case ServerConnectionState.disconnected:
return s.disconnected; return _s.disconnected;
case ServerConnectionState.connected: case ServerConnectionState.connected:
if (temp == '') { if (temp == '') {
if (upTime == '') { if (upTime == '') {
return s.serverTabLoading; return _s.serverTabLoading;
} else { } else {
return upTime; return upTime;
} }
@@ -264,17 +263,17 @@ class _ServerPageState extends State<ServerPage>
} }
} }
case ServerConnectionState.connecting: case ServerConnectionState.connecting:
return s.serverTabConnecting; return _s.serverTabConnecting;
case ServerConnectionState.failed: case ServerConnectionState.failed:
if (failedInfo == null) { if (failedInfo == null) {
return s.serverTabFailed; return _s.serverTabFailed;
} }
if (failedInfo.contains('encypted')) { if (failedInfo.contains('encypted')) {
return s.serverTabPlzSave; return _s.serverTabPlzSave;
} }
return failedInfo; return failedInfo;
default: default:
return s.serverTabUnkown; return _s.serverTabUnkown;
} }
} }

View File

@@ -30,7 +30,7 @@ class _SettingPageState extends State<SettingPage> {
late final ServerProvider _serverProvider; late final ServerProvider _serverProvider;
late MediaQueryData _media; late MediaQueryData _media;
late ThemeData _theme; late ThemeData _theme;
late S s; late S _s;
var _intervalValue = 0.0; var _intervalValue = 0.0;
@@ -40,7 +40,7 @@ class _SettingPageState extends State<SettingPage> {
priColor = primaryColor; priColor = primaryColor;
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
_theme = Theme.of(context); _theme = Theme.of(context);
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -56,7 +56,7 @@ class _SettingPageState extends State<SettingPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.setting), title: Text(_s.setting),
), ),
body: ListView( body: ListView(
padding: const EdgeInsets.all(17), padding: const EdgeInsets.all(17),
@@ -76,12 +76,12 @@ class _SettingPageState extends State<SettingPage> {
String display; String display;
if (app.newestBuild != null) { if (app.newestBuild != null) {
if (app.newestBuild! > BuildData.build) { if (app.newestBuild! > BuildData.build) {
display = s.versionHaveUpdate(app.newestBuild!); display = _s.versionHaveUpdate(app.newestBuild!);
} else { } else {
display = s.versionUpdated(BuildData.build); display = _s.versionUpdated(BuildData.build);
} }
} else { } else {
display = s.versionUnknownUpdate(BuildData.build); display = _s.versionUnknownUpdate(BuildData.build);
} }
return ListTile( return ListTile(
contentPadding: roundRectCardPadding, contentPadding: roundRectCardPadding,
@@ -103,15 +103,15 @@ class _SettingPageState extends State<SettingPage> {
childrenPadding: roundRectCardPadding, childrenPadding: roundRectCardPadding,
textColor: priColor, textColor: priColor,
title: Text( title: Text(
s.updateServerStatusInterval, _s.updateServerStatusInterval,
style: textSize13, style: textSize13,
textAlign: TextAlign.start, textAlign: TextAlign.start,
), ),
subtitle: Text( subtitle: Text(
s.willTakEeffectImmediately, _s.willTakEeffectImmediately,
style: const TextStyle(color: Colors.grey, fontSize: 13), style: const TextStyle(color: Colors.grey, fontSize: 13),
), ),
trailing: Text('${_intervalValue.toInt()} ${s.second}'), trailing: Text('${_intervalValue.toInt()} ${_s.second}'),
children: [ children: [
Slider( Slider(
thumbColor: priColor, thumbColor: priColor,
@@ -128,7 +128,7 @@ class _SettingPageState extends State<SettingPage> {
_store.serverStatusUpdateInterval.put(val.toInt()); _store.serverStatusUpdateInterval.put(val.toInt());
_serverProvider.startAutoRefresh(); _serverProvider.startAutoRefresh();
}, },
label: '${_intervalValue.toInt()} ${s.second}', label: '${_intervalValue.toInt()} ${_s.second}',
divisions: 10, divisions: 10,
), ),
const SizedBox( const SizedBox(
@@ -136,7 +136,7 @@ class _SettingPageState extends State<SettingPage> {
), ),
_intervalValue == 0.0 _intervalValue == 0.0
? Text( ? Text(
s.updateIntervalEqual0, _s.updateIntervalEqual0,
style: const TextStyle(color: Colors.grey, fontSize: 12), style: const TextStyle(color: Colors.grey, fontSize: 12),
textAlign: TextAlign.center, textAlign: TextAlign.center,
) )
@@ -161,7 +161,7 @@ class _SettingPageState extends State<SettingPage> {
), ),
), ),
title: Text( title: Text(
s.appPrimaryColor, _s.appPrimaryColor,
style: textSize13, style: textSize13,
), ),
children: [_buildAppColorPicker(priColor), _buildColorPickerConfirmBtn()], children: [_buildAppColorPicker(priColor), _buildColorPickerConfirmBtn()],
@@ -193,7 +193,7 @@ class _SettingPageState extends State<SettingPage> {
tilePadding: roundRectCardPadding, tilePadding: roundRectCardPadding,
childrenPadding: roundRectCardPadding, childrenPadding: roundRectCardPadding,
title: Text( title: Text(
s.launchPage, _s.launchPage,
style: textSize13, style: textSize13,
), ),
trailing: ConstrainedBox( trailing: ConstrainedBox(

View File

@@ -23,8 +23,7 @@ class SFTPDownloadedPage extends StatefulWidget {
class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> { class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
PathWithPrefix? _path; PathWithPrefix? _path;
String? _prefixPath; String? _prefixPath;
late S s; late S _s;
late ThemeData _theme;
@override @override
void initState() { void initState() {
@@ -39,15 +38,14 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
_theme = Theme.of(context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.download), title: Text(_s.download),
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.downloading), icon: const Icon(Icons.downloading),
@@ -68,7 +66,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: (() { onPressed: (() {
if (_path!.path == _prefixPath) { if (_path!.path == _prefixPath) {
showSnackBar(context, Text(s.alreadyLastDir)); showSnackBar(context, Text(_s.alreadyLastDir));
return; return;
} }
_path!.update('..'); _path!.update('..');
@@ -80,18 +78,13 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
} }
Widget _buildPath() { Widget _buildPath() {
final color = _theme.scaffoldBackgroundColor;
return Container( return Container(
color: color,
padding: const EdgeInsets.fromLTRB(11, 7, 11, 11), padding: const EdgeInsets.fromLTRB(11, 7, 11, 11),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Divider(), const Divider(),
(_path?.path ?? s.loadingFiles).omitStartStr( (_path?.path ?? _s.loadingFiles).omitStartStr(),
style: TextStyle(
color: color.isBrightColor ? Colors.black : Colors.white),
)
], ],
), ),
); );
@@ -142,30 +135,30 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
final fileName = file.path.split('/').last; final fileName = file.path.split('/').last;
showRoundDialog( showRoundDialog(
context, context,
s.choose, _s.choose,
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
ListTile( ListTile(
leading: const Icon(Icons.delete), leading: const Icon(Icons.delete),
title: Text(s.delete), title: Text(_s.delete),
onTap: () { onTap: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
showRoundDialog( showRoundDialog(
context, context,
s.sureDelete(fileName), _s.sureDelete(fileName),
const SizedBox(), const SizedBox(),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel)), child: Text(_s.cancel)),
TextButton( TextButton(
onPressed: () { onPressed: () {
file.deleteSync(); file.deleteSync();
setState(() {}); setState(() {});
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text(s.ok), child: Text(_s.ok),
), ),
], ],
); );
@@ -173,7 +166,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
), ),
ListTile( ListTile(
leading: const Icon(Icons.open_in_new), leading: const Icon(Icons.open_in_new),
title: Text(s.open), title: Text(_s.open),
onTap: () { onTap: () {
shareFiles(context, [file.absolute.path]); shareFiles(context, [file.absolute.path]);
}, },
@@ -183,7 +176,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
[ [
TextButton( TextButton(
onPressed: (() => Navigator.of(context).pop()), onPressed: (() => Navigator.of(context).pop()),
child: Text(s.close)) child: Text(_s.close))
], ],
); );
} }

View File

@@ -17,12 +17,12 @@ class SFTPDownloadingPage extends StatefulWidget {
} }
class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> { class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
late S s; late S _s;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -30,7 +30,7 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text( title: Text(
s.download, _s.download,
style: textSize18, style: textSize18,
), ),
), ),
@@ -42,7 +42,7 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
return Consumer<SftpDownloadProvider>(builder: (__, pro, _) { return Consumer<SftpDownloadProvider>(builder: (__, pro, _) {
if (pro.status.isEmpty) { if (pro.status.isEmpty) {
return Center( return Center(
child: Text(s.sftpNoDownloadTask), child: Text(_s.sftpNoDownloadTask),
); );
} }
return ListView.builder( return ListView.builder(
@@ -81,7 +81,7 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
final time = status.spentTime.toString(); final time = status.spentTime.toString();
return _wrapInCard( return _wrapInCard(
status, status,
'${s.downloadFinished} ${s.spentTime(time == 'null' ? s.unknown : (time.substring(0, time.length - 7)))}', '${_s.downloadFinished} ${_s.spentTime(time == 'null' ? _s.unknown : (time.substring(0, time.length - 7)))}',
trailing: IconButton( trailing: IconButton(
onPressed: () => shareFiles(context, [status.item.localPath]), onPressed: () => shareFiles(context, [status.item.localPath]),
icon: const Icon(Icons.open_in_new), icon: const Icon(Icons.open_in_new),
@@ -90,18 +90,18 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
case SftpWorkerStatus.downloading: case SftpWorkerStatus.downloading:
return _wrapInCard( return _wrapInCard(
status, status,
s.downloadStatus((status.progress ?? 0.0).toStringAsFixed(2), _s.downloadStatus((status.progress ?? 0.0).toStringAsFixed(2),
(status.size ?? 0).convertBytes), (status.size ?? 0).convertBytes),
trailing: trailing:
CircularProgressIndicator(value: (status.progress ?? 0) / 100)); CircularProgressIndicator(value: (status.progress ?? 0) / 100));
case SftpWorkerStatus.preparing: case SftpWorkerStatus.preparing:
return _wrapInCard(status, s.sftpDlPrepare, trailing: loadingIcon); return _wrapInCard(status, _s.sftpDlPrepare, trailing: loadingIcon);
case SftpWorkerStatus.sshConnectted: case SftpWorkerStatus.sshConnectted:
return _wrapInCard(status, s.sftpSSHConnected, trailing: loadingIcon); return _wrapInCard(status, _s.sftpSSHConnected, trailing: loadingIcon);
default: default:
return _wrapInCard( return _wrapInCard(
status, status,
s.unknown, _s.unknown,
trailing: const Icon( trailing: const Icon(
Icons.error, Icons.error,
size: 40, size: 40,

View File

@@ -35,13 +35,13 @@ class _SFTPPageState extends State<SFTPPage> {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
late MediaQueryData _media; late MediaQueryData _media;
late S s; late S _s;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
s = S.of(context); _s = S.of(context);
} }
@override @override
@@ -61,24 +61,24 @@ class _SFTPPageState extends State<SFTPPage> {
IconButton( IconButton(
onPressed: (() => showRoundDialog( onPressed: (() => showRoundDialog(
context, context,
s.choose, _s.choose,
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
ListTile( ListTile(
leading: const Icon(Icons.folder), leading: const Icon(Icons.folder),
title: Text(s.createFolder), title: Text(_s.createFolder),
onTap: () => mkdir(context)), onTap: () => mkdir(context)),
ListTile( ListTile(
leading: const Icon(Icons.insert_drive_file), leading: const Icon(Icons.insert_drive_file),
title: Text(s.createFile), title: Text(_s.createFile),
onTap: () => newFile(context)), onTap: () => newFile(context)),
], ],
), ),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.close)) child: Text(_s.close))
], ],
)), )),
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
@@ -167,24 +167,24 @@ class _SFTPPageState extends State<SFTPPage> {
void onItemPress(BuildContext context, SftpName file, bool showDownload) { void onItemPress(BuildContext context, SftpName file, bool showDownload) {
showRoundDialog( showRoundDialog(
context, context,
s.choose, _s.choose,
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
ListTile( ListTile(
leading: const Icon(Icons.delete), leading: const Icon(Icons.delete),
title: Text(s.delete), title: Text(_s.delete),
onTap: () => delete(context, file), onTap: () => delete(context, file),
), ),
ListTile( ListTile(
leading: const Icon(Icons.edit), leading: const Icon(Icons.edit),
title: Text(s.rename), title: Text(_s.rename),
onTap: () => rename(context, file), onTap: () => rename(context, file),
), ),
showDownload showDownload
? ListTile( ? ListTile(
leading: const Icon(Icons.download), leading: const Icon(Icons.download),
title: Text(s.download), title: Text(_s.download),
onTap: () => download(context, file), onTap: () => download(context, file),
) )
: const SizedBox() : const SizedBox()
@@ -192,7 +192,8 @@ class _SFTPPageState extends State<SFTPPage> {
), ),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), child: Text(s.cancel)) onPressed: () => Navigator.of(context).pop(),
child: Text(_s.cancel))
], ],
); );
} }
@@ -200,12 +201,12 @@ class _SFTPPageState extends State<SFTPPage> {
void download(BuildContext context, SftpName name) { void download(BuildContext context, SftpName name) {
showRoundDialog( showRoundDialog(
context, context,
s.download, _s.download,
Text('${s.dl2Local(name.filename)}\n${s.keepForeground}'), Text('${_s.dl2Local(name.filename)}\n${_s.keepForeground}'),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel)), child: Text(_s.cancel)),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
Navigator.of(context).pop(); Navigator.of(context).pop();
@@ -229,12 +230,12 @@ class _SFTPPageState extends State<SFTPPage> {
Navigator.of(context).pop(); Navigator.of(context).pop();
showRoundDialog( showRoundDialog(
context, context,
s.goSftpDlPage, _s.goSftpDlPage,
const SizedBox(), const SizedBox(),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
TextButton( TextButton(
onPressed: () { onPressed: () {
@@ -242,12 +243,12 @@ class _SFTPPageState extends State<SFTPPage> {
AppRoute(const SFTPDownloadingPage(), 'sftp downloading') AppRoute(const SFTPDownloadingPage(), 'sftp downloading')
.go(context); .go(context);
}, },
child: Text(s.ok), child: Text(_s.ok),
) )
], ],
); );
}, },
child: Text(s.download), child: Text(_s.download),
) )
], ],
); );
@@ -257,8 +258,8 @@ class _SFTPPageState extends State<SFTPPage> {
Navigator.of(context).pop(); Navigator.of(context).pop();
showRoundDialog( showRoundDialog(
context, context,
s.attention, _s.attention,
Text(s.sureDelete(file.filename)), Text(_s.sureDelete(file.filename)),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
@@ -270,7 +271,7 @@ class _SFTPPageState extends State<SFTPPage> {
listDir(); listDir();
}, },
child: Text( child: Text(
s.delete, _s.delete,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
), ),
@@ -283,29 +284,29 @@ class _SFTPPageState extends State<SFTPPage> {
final textController = TextEditingController(); final textController = TextEditingController();
showRoundDialog( showRoundDialog(
context, context,
s.createFolder, _s.createFolder,
TextField( TextField(
controller: textController, controller: textController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.name, labelText: _s.name,
), ),
), ),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
TextButton( TextButton(
onPressed: () { onPressed: () {
if (textController.text == '') { if (textController.text == '') {
showRoundDialog( showRoundDialog(
context, context,
s.attention, _s.attention,
Text(s.fieldMustNotEmpty), Text(_s.fieldMustNotEmpty),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.ok)), child: Text(_s.ok)),
], ],
); );
return; return;
@@ -316,7 +317,7 @@ class _SFTPPageState extends State<SFTPPage> {
listDir(); listDir();
}, },
child: Text( child: Text(
s.ok, _s.ok,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
), ),
@@ -329,29 +330,29 @@ class _SFTPPageState extends State<SFTPPage> {
final textController = TextEditingController(); final textController = TextEditingController();
showRoundDialog( showRoundDialog(
context, context,
s.createFile, _s.createFile,
TextField( TextField(
controller: textController, controller: textController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.name, labelText: _s.name,
), ),
), ),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
if (textController.text == '') { if (textController.text == '') {
showRoundDialog( showRoundDialog(
context, context,
s.attention, _s.attention,
Text(s.fieldMustNotEmpty), Text(_s.fieldMustNotEmpty),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.ok), child: Text(_s.ok),
), ),
], ],
); );
@@ -364,7 +365,7 @@ class _SFTPPageState extends State<SFTPPage> {
listDir(); listDir();
}, },
child: Text( child: Text(
s.ok, _s.ok,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
), ),
@@ -377,28 +378,28 @@ class _SFTPPageState extends State<SFTPPage> {
final textController = TextEditingController(); final textController = TextEditingController();
showRoundDialog( showRoundDialog(
context, context,
s.rename, _s.rename,
TextField( TextField(
controller: textController, controller: textController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.name, labelText: _s.name,
), ),
), ),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel)), child: Text(_s.cancel)),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
if (textController.text == '') { if (textController.text == '') {
showRoundDialog( showRoundDialog(
context, context,
s.attention, _s.attention,
Text(s.fieldMustNotEmpty), Text(_s.fieldMustNotEmpty),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.ok), child: Text(_s.ok),
), ),
], ],
); );
@@ -409,7 +410,7 @@ class _SFTPPageState extends State<SFTPPage> {
listDir(); listDir();
}, },
child: Text( child: Text(
s.rename, _s.rename,
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
), ),
@@ -440,12 +441,12 @@ class _SFTPPageState extends State<SFTPPage> {
} catch (e) { } catch (e) {
await showRoundDialog( await showRoundDialog(
context, context,
s.error, _s.error,
Text(e.toString()), Text(e.toString()),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.ok), child: Text(_s.ok),
) )
], ],
); );
@@ -458,7 +459,7 @@ class _SFTPPageState extends State<SFTPPage> {
Widget _buildDestSelector() { Widget _buildDestSelector() {
final str = _status.path?.path; final str = _status.path?.path;
return ExpansionTile( return ExpansionTile(
title: Text(_status.spi?.name ?? s.chooseDestination), title: Text(_status.spi?.name ?? _s.chooseDestination),
subtitle: _status.selected subtitle: _status.selected
? str!.omitStartStr(style: const TextStyle(color: Colors.grey)) ? str!.omitStartStr(style: const TextStyle(color: Colors.grey))
: null, : null,

View File

@@ -19,12 +19,12 @@ class SnippetEditPage extends StatefulWidget {
class _SnippetEditPageState extends State<SnippetEditPage> class _SnippetEditPageState extends State<SnippetEditPage>
with AfterLayoutMixin { with AfterLayoutMixin {
final nameController = TextEditingController(); final _nameController = TextEditingController();
final scriptController = TextEditingController(); final _scriptController = TextEditingController();
final scriptNode = FocusNode(); final _scriptNode = FocusNode();
late SnippetProvider _provider; late SnippetProvider _provider;
late S s; late S _s;
@override @override
void initState() { void initState() {
@@ -35,14 +35,14 @@ class _SnippetEditPageState extends State<SnippetEditPage>
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.edit, style: textSize18), title: Text(_s.edit, style: textSize18),
actions: [ actions: [
widget.snippet != null widget.snippet != null
? IconButton( ? IconButton(
@@ -50,7 +50,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
_provider.del(widget.snippet!); _provider.del(widget.snippet!);
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
tooltip: s.delete, tooltip: _s.delete,
icon: const Icon(Icons.delete)) icon: const Icon(Icons.delete))
: const SizedBox() : const SizedBox()
], ],
@@ -59,30 +59,31 @@ class _SnippetEditPageState extends State<SnippetEditPage>
padding: const EdgeInsets.all(13), padding: const EdgeInsets.all(13),
children: [ children: [
TextField( TextField(
controller: nameController, controller: _nameController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
onSubmitted: (_) => FocusScope.of(context).requestFocus(scriptNode), onSubmitted: (_) =>
decoration: buildDecoration(s.name, icon: Icons.info), FocusScope.of(context).requestFocus(_scriptNode),
decoration: buildDecoration(_s.name, icon: Icons.info),
), ),
TextField( TextField(
controller: scriptController, controller: _scriptController,
autocorrect: false, autocorrect: false,
focusNode: scriptNode, focusNode: _scriptNode,
minLines: 3, minLines: 3,
maxLines: 10, maxLines: 10,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
enableSuggestions: false, enableSuggestions: false,
decoration: buildDecoration(s.snippet, icon: Icons.code), decoration: buildDecoration(_s.snippet, icon: Icons.code),
), ),
], ],
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
child: const Icon(Icons.send), child: const Icon(Icons.send),
onPressed: () { onPressed: () {
final name = nameController.text; final name = _nameController.text;
final script = scriptController.text; final script = _scriptController.text;
if (name.isEmpty || script.isEmpty) { if (name.isEmpty || script.isEmpty) {
showSnackBar(context, Text(s.fieldMustNotEmpty)); showSnackBar(context, Text(_s.fieldMustNotEmpty));
return; return;
} }
final snippet = Snippet(name, script); final snippet = Snippet(name, script);
@@ -100,8 +101,8 @@ class _SnippetEditPageState extends State<SnippetEditPage>
@override @override
void afterFirstLayout(BuildContext context) { void afterFirstLayout(BuildContext context) {
if (widget.snippet != null) { if (widget.snippet != null) {
nameController.text = widget.snippet!.name; _nameController.text = widget.snippet!.name;
scriptController.text = widget.snippet!.script; _scriptController.text = widget.snippet!.script;
} }
} }
} }

View File

@@ -27,19 +27,19 @@ class _SnippetListPageState extends State<SnippetListPage> {
final _textStyle = TextStyle(color: primaryColor); final _textStyle = TextStyle(color: primaryColor);
late S s; late S _s;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
s = S.of(context); _s = S.of(context);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(s.snippet, style: textSize18), title: Text(_s.snippet, style: textSize18),
), ),
body: _buildBody(), body: _buildBody(),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
@@ -79,7 +79,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
'snippet edit page') 'snippet edit page')
.go(context), .go(context),
child: Text( child: Text(
s.edit, _s.edit,
style: _textStyle, style: _textStyle,
), ),
), ),
@@ -93,7 +93,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
run(context, snippet); run(context, snippet);
}, },
child: Text( child: Text(
s.run, _s.run,
style: _textStyle, style: _textStyle,
), ),
) )
@@ -106,7 +106,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
}, },
) )
: Center( : Center(
child: Text(s.noSavedSnippet), child: Text(_s.noSavedSnippet),
); );
}, },
); );
@@ -115,11 +115,11 @@ class _SnippetListPageState extends State<SnippetListPage> {
void _showRunDialog(Snippet snippet) { void _showRunDialog(Snippet snippet) {
showRoundDialog( showRoundDialog(
context, context,
s.chooseDestination, _s.chooseDestination,
Consumer<ServerProvider>( Consumer<ServerProvider>(
builder: (_, provider, __) { builder: (_, provider, __) {
if (provider.servers.isEmpty) { if (provider.servers.isEmpty) {
return Text(s.noServerAvailable); return Text(_s.noServerAvailable);
} }
_selectedIndex = provider.servers.first.info; _selectedIndex = provider.servers.first.info;
return SizedBox( return SizedBox(
@@ -163,11 +163,11 @@ class _SnippetListPageState extends State<SnippetListPage> {
[ [
TextButton( TextButton(
onPressed: () async => run(context, snippet), onPressed: () async => run(context, snippet),
child: Text(s.run), child: Text(_s.run),
), ),
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel), child: Text(_s.cancel),
), ),
], ],
); );
@@ -179,12 +179,12 @@ class _SnippetListPageState extends State<SnippetListPage> {
if (result != null) { if (result != null) {
showRoundDialog( showRoundDialog(
context, context,
s.result, _s.result,
Text(result, style: const TextStyle(fontSize: 13)), Text(result, style: const TextStyle(fontSize: 13)),
[ [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.close), child: Text(_s.close),
) )
], ],
); );