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

View File

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

View File

@@ -21,7 +21,7 @@ class _ConvertPageState extends State<ConvertPage>
late TextEditingController _textEditingControllerResult;
late MediaQueryData _media;
late ThemeData _theme;
late S s;
late S _s;
int _typeOptionIndex = 0;
@@ -37,7 +37,7 @@ class _ConvertPageState extends State<ConvertPage>
super.didChangeDependencies();
_media = MediaQuery.of(context);
_theme = Theme.of(context);
s = S.of(context);
_s = S.of(context);
}
@override
@@ -65,7 +65,7 @@ class _ConvertPageState extends State<ConvertPage>
showSnackBar(context, Text('Error: \n$e'));
}
},
tooltip: s.convert,
tooltip: _s.convert,
heroTag: 'convert fab',
child: const Icon(Icons.send),
),
@@ -84,7 +84,7 @@ class _ConvertPageState extends State<ConvertPage>
case 3:
return Uri.decodeFull(text);
default:
return s.unkownConvertMode;
return _s.unkownConvertMode;
}
}
@@ -96,8 +96,8 @@ class _ConvertPageState extends State<ConvertPage>
}
Widget _buildTypeOption() {
final decode = s.decode;
final encode = s.encode;
final decode = _s.decode;
final encode = _s.encode;
final List<String> typeOption = [
'Base64 $decode',
'Base64 $encode',
@@ -113,7 +113,7 @@ class _ConvertPageState extends State<ConvertPage>
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(primaryColor)),
child: Icon(Icons.change_circle, semanticLabel: s.upsideDown),
child: Icon(Icons.change_circle, semanticLabel: _s.upsideDown),
onPressed: () {
final temp = _textEditingController.text;
_textEditingController.text = _textEditingControllerResult.text;
@@ -124,7 +124,7 @@ class _ConvertPageState extends State<ConvertPage>
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(primaryColor),
),
child: Icon(Icons.copy, semanticLabel: s.copy),
child: Icon(Icons.copy, semanticLabel: _s.copy),
onPressed: () => Clipboard.setData(
ClipboardData(
text: _textEditingControllerResult.text == ''
@@ -150,7 +150,7 @@ class _ConvertPageState extends State<ConvertPage>
color: primaryColor),
),
Text(
s.currentMode,
_s.currentMode,
textScaleFactor: 1.0,
textAlign: TextAlign.right,
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/server.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/store/docker.dart';
import 'package:toolbox/generated/l10n.dart';
@@ -26,9 +27,8 @@ class DockerManagePage extends StatefulWidget {
class _DockerManagePageState extends State<DockerManagePage> {
final _docker = locator<DockerProvider>();
final greyTextStyle = const TextStyle(color: Colors.grey);
final textController = TextEditingController();
late S s;
final _textController = TextEditingController();
late S _s;
@override
void dispose() {
@@ -39,7 +39,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
s = S.of(context);
_s = S.of(context);
}
@override
@@ -50,7 +50,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
.firstWhere((element) => element.info == widget.spi)
.client;
if (client == null) {
showSnackBar(context, Text(s.noClient));
showSnackBar(context, Text(_s.noClient));
Navigator.of(context).pop();
return;
}
@@ -90,14 +90,14 @@ class _DockerManagePageState extends State<DockerManagePage> {
final argsCtrl = TextEditingController();
await showRoundDialog(
context,
s.newContainer,
_s.newContainer,
Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: s.dockerImage, hintText: 'ubuntu:22.10'),
labelText: _s.dockerImage, hintText: 'ubuntu:22.10'),
controller: imageCtrl,
autocorrect: false,
),
@@ -105,14 +105,15 @@ class _DockerManagePageState extends State<DockerManagePage> {
keyboardType: TextInputType.text,
controller: nameCtrl,
decoration: InputDecoration(
labelText: s.dockerContainerName, hintText: 'ubuntu22'),
labelText: _s.dockerContainerName, hintText: 'ubuntu22'),
autocorrect: false,
),
TextField(
keyboardType: TextInputType.text,
controller: argsCtrl,
decoration: InputDecoration(
labelText: s.extraArgs, hintText: '-p 2222:22 -v ~/.xxx/:/xxx'),
labelText: _s.extraArgs,
hintText: '-p 2222:22 -v ~/.xxx/:/xxx'),
autocorrect: false,
),
],
@@ -120,7 +121,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel),
child: Text(_s.cancel),
),
TextButton(
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 {
await showRoundDialog(
context,
s.preview,
_s.preview,
Text(cmd),
[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel),
child: Text(_s.cancel),
),
TextButton(
onPressed: () async {
Navigator.of(context).pop();
final result = await _docker.run(cmd);
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() {
if (textController.text == '') {
showRoundDialog(context, s.attention, Text(s.fieldMustNotEmpty), [
if (_textController.text == '') {
showRoundDialog(context, _s.attention, Text(_s.fieldMustNotEmpty), [
TextButton(
onPressed: () => Navigator.of(context).pop(), child: Text(s.ok)),
onPressed: () => Navigator.of(context).pop(), child: Text(_s.ok)),
]);
return;
}
@@ -200,12 +201,12 @@ class _DockerManagePageState extends State<DockerManagePage> {
context,
widget.spi.user,
TextField(
controller: textController,
controller: _textController,
keyboardType: TextInputType.visiblePassword,
obscureText: true,
onSubmitted: (_) => onSubmitted(),
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();
},
child: Text(s.cancel),
child: Text(_s.cancel),
),
TextButton(
onPressed: () => onSubmitted(),
child: Text(
s.ok,
_s.ok,
style: const TextStyle(color: Colors.red),
),
),
],
);
return textController.text.trim();
return _textController.text.trim();
}
Widget _buildMain(DockerProvider docker) {
@@ -260,7 +261,8 @@ class _DockerManagePageState extends State<DockerManagePage> {
padding: const EdgeInsets.all(7),
children: [
_buildLoading(docker),
_buildVersion(docker.edition ?? s.unknown, docker.version ?? s.unknown),
_buildVersion(
docker.edition ?? _s.unknown, docker.version ?? _s.unknown),
_buildPsItems(running, docker),
_buildImages(docker),
_buildEditHost(running, docker),
@@ -273,10 +275,10 @@ class _DockerManagePageState extends State<DockerManagePage> {
return const SizedBox();
}
return ExpansionTile(
title: Text(s.imagesList),
title: Text(_s.imagesList),
subtitle: Text(
s.dockerImagesFmt(docker.images!.length),
style: greyTextStyle,
_s.dockerImagesFmt(docker.images!.length),
style: grey,
),
children: docker.images!
.map(
@@ -289,7 +291,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
final result = await _docker.run('docker rmi ${e.id} -f');
if (result != null) {
showSnackBar(
context, Text(getErrMsg(result) ?? s.unknownError));
context, Text(getErrMsg(result) ?? _s.unknownError));
}
},
),
@@ -322,12 +324,12 @@ class _DockerManagePageState extends State<DockerManagePage> {
child: Column(
children: [
Text(
s.dockerEmptyRunningItems,
_s.dockerEmptyRunningItems,
textAlign: TextAlign.center,
),
TextButton(
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 {
await showRoundDialog(
context,
s.dockerEditHost,
_s.dockerEditHost,
TextField(
maxLines: 1,
autocorrect: false,
@@ -352,7 +354,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel),
child: Text(_s.cancel),
),
],
);
@@ -362,16 +364,16 @@ class _DockerManagePageState extends State<DockerManagePage> {
var errStr = '';
switch (err.type) {
case DockerErrType.noClient:
errStr = s.noClient;
errStr = _s.noClient;
break;
case DockerErrType.notInstalled:
errStr = s.dockerNotInstalled;
errStr = _s.dockerNotInstalled;
break;
case DockerErrType.invalidVersion:
errStr = s.invalidVersion;
errStr = _s.invalidVersion;
break;
default:
errStr = err.message ?? s.unknown;
errStr = err.message ?? _s.unknown;
}
return Text(errStr);
}
@@ -380,18 +382,18 @@ class _DockerManagePageState extends State<DockerManagePage> {
switch (err.type) {
case DockerErrType.notInstalled:
return UrlText(
text: s.installDockerWithUrl,
replace: s.install,
text: _s.installDockerWithUrl,
replace: _s.install,
);
case DockerErrType.noClient:
return Text(s.waitConnection);
return Text(_s.waitConnection);
case DockerErrType.invalidVersion:
return UrlText(
text: s.invalidVersionHelp(issueUrl),
text: _s.invalidVersionHelp(issueUrl),
replace: 'Github',
);
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) {
return ExpansionTile(
title: Text(s.containerStatus),
subtitle: Text(_buildSubtitle(running), style: greyTextStyle),
title: Text(_s.containerStatus),
subtitle: Text(_buildSubtitle(running), style: grey),
children: running.map(
(item) {
return ListTile(
@@ -437,7 +439,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
],
onSelected: (value) {
if (busy) {
showSnackBar(context, Text(s.isBusy));
showSnackBar(context, Text(_s.isBusy));
return;
}
final item = value as DropdownBtnItem;
@@ -460,8 +462,8 @@ class _DockerManagePageState extends State<DockerManagePage> {
final runningCount = running.where((element) => element.running).length;
final stoped = running.length - runningCount;
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 int _selectIndex;
late double _width;
late S s;
late S _s;
@override
void initState() {
@@ -59,7 +59,7 @@ class _MyHomePageState extends State<MyHomePage>
@override
void didChangeDependencies() {
super.didChangeDependencies();
s = S.of(context);
_s = S.of(context);
_width = MediaQuery.of(context).size.width;
}
@@ -84,20 +84,6 @@ class _MyHomePageState extends State<MyHomePage>
@override
Widget build(BuildContext 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(
drawer: _buildDrawer(),
appBar: AppBar(
@@ -105,7 +91,7 @@ class _MyHomePageState extends State<MyHomePage>
actions: [
IconButton(
icon: const Icon(Icons.developer_mode, size: 23),
tooltip: s.debug,
tooltip: _s.debug,
onPressed: () =>
AppRoute(const DebugPage(), 'Debug Page').go(context),
),
@@ -126,7 +112,6 @@ class _MyHomePageState extends State<MyHomePage>
}
Widget _buildItem(int idx, NavigationItem item, bool isSelected) {
bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
final width = _width / tabItems.length;
return AnimatedContainer(
duration: const Duration(milliseconds: 377),
@@ -135,7 +120,7 @@ class _MyHomePageState extends State<MyHomePage>
width: isSelected ? width : width - 17,
decoration: BoxDecoration(
color: isSelected
? isDarkMode
? isDarkMode(context)
? Colors.white12
: Colors.black.withOpacity(0.07)
: Colors.transparent,
@@ -195,57 +180,57 @@ class _MyHomePageState extends State<MyHomePage>
children: [
ListTile(
leading: const Icon(Icons.settings),
title: Text(s.setting),
title: Text(_s.setting),
onTap: () =>
AppRoute(const SettingPage(), 'Setting').go(context),
),
ListTile(
leading: const Icon(Icons.vpn_key),
title: Text(s.privateKey),
title: Text(_s.privateKey),
onTap: () => AppRoute(
const StoredPrivateKeysPage(), 'private key list')
.go(context),
),
ListTile(
leading: const Icon(Icons.download),
title: Text(s.download),
title: Text(_s.download),
onTap: () =>
AppRoute(const SFTPDownloadedPage(), 'snippet list')
.go(context),
),
ListTile(
leading: const Icon(Icons.import_export),
title: Text(s.backup),
title: Text(_s.backup),
onTap: () =>
AppRoute(BackupPage(), 'backup page').go(context),
),
ListTile(
leading: const Icon(Icons.info),
title: Text(s.feedback),
title: Text(_s.feedback),
onTap: () => showRoundDialog(
context,
s.feedback,
Text(s.feedbackOnGithub),
_s.feedback,
Text(_s.feedbackOnGithub),
[
TextButton(
onPressed: () => Clipboard.setData(
const ClipboardData(text: issueUrl)),
child: Text(s.copy),
child: Text(_s.copy),
),
TextButton(
onPressed: () => openUrl(issueUrl),
child: Text(s.feedback),
child: Text(_s.feedback),
),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(s.close),
child: Text(_s.close),
)
],
),
),
ListTile(
leading: const Icon(Icons.snippet_folder),
title: Text(s.snippet),
title: Text(_s.snippet),
onTap: () => AppRoute(const SnippetListPage(), 'snippet list')
.go(context),
),
@@ -256,9 +241,10 @@ class _MyHomePageState extends State<MyHomePage>
applicationIcon: _buildIcon(),
aboutBoxChildren: [
UrlText(
text: s.madeWithLove(myGithub), replace: 'lollipopkit'),
text: _s.madeWithLove(myGithub),
replace: 'lollipopkit'),
UrlText(
text: s.aboutThanks,
text: _s.aboutThanks,
),
const UrlText(
text: rainSunMeGithub,
@@ -269,7 +255,7 @@ class _MyHomePageState extends State<MyHomePage>
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/provider/server.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/locator.dart';
import 'package:toolbox/view/widget/input_field.dart';
@@ -29,9 +30,6 @@ class _PingPageState extends State<PingPage>
final List<PingResult> _results = [];
final _serverProvider = locator<ServerProvider>();
late S s;
static const summaryTextStyle = TextStyle(
fontSize: 12,
);
@override
void initState() {
@@ -103,7 +101,7 @@ class _PingPageState extends State<PingPage>
),
subtitle: Text(
_buildPingSummary(result, unknown, ms),
style: summaryTextStyle,
style: textSize11,
),
trailing: Text(
'${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>
with AfterLayoutMixin {
final nameController = TextEditingController();
final keyController = TextEditingController();
final pwdController = TextEditingController();
final nameNode = FocusNode();
final keyNode = FocusNode();
final pwdNode = FocusNode();
late FocusScopeNode focusScope;
final _nameController = TextEditingController();
final _keyController = TextEditingController();
final _pwdController = TextEditingController();
final _nameNode = FocusNode();
final _keyNode = FocusNode();
final _pwdNode = FocusNode();
late FocusScopeNode _focusScope;
late PrivateKeyProvider _provider;
late Widget loading;
late S s;
late S _s;
Widget _loading = const SizedBox();
@override
void initState() {
super.initState();
_provider = locator<PrivateKeyProvider>();
loading = const SizedBox();
_loading = const SizedBox();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
s = S.of(context);
focusScope = FocusScope.of(context);
_s = S.of(context);
_focusScope = FocusScope.of(context);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(s.edit, style: textSize18),
title: Text(_s.edit, style: textSize18),
actions: [
widget.info != null
? IconButton(
tooltip: s.delete,
tooltip: _s.delete,
onPressed: () {
_provider.delInfo(widget.info!);
Navigator.of(context).pop();
@@ -69,48 +69,48 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
padding: const EdgeInsets.all(13),
children: [
TextField(
controller: nameController,
controller: _nameController,
keyboardType: TextInputType.text,
focusNode: nameNode,
onSubmitted: (_) => focusScope.requestFocus(keyNode),
decoration: buildDecoration(s.name, icon: Icons.info),
focusNode: _nameNode,
onSubmitted: (_) => _focusScope.requestFocus(_keyNode),
decoration: buildDecoration(_s.name, icon: Icons.info),
),
TextField(
controller: keyController,
controller: _keyController,
autocorrect: false,
minLines: 3,
maxLines: 10,
keyboardType: TextInputType.text,
focusNode: keyNode,
onSubmitted: (_) => focusScope.requestFocus(pwdNode),
focusNode: _keyNode,
onSubmitted: (_) => _focusScope.requestFocus(_pwdNode),
enableSuggestions: false,
decoration: buildDecoration(s.privateKey, icon: Icons.vpn_key),
decoration: buildDecoration(_s.privateKey, icon: Icons.vpn_key),
),
TextField(
controller: pwdController,
controller: _pwdController,
autocorrect: false,
keyboardType: TextInputType.text,
focusNode: pwdNode,
focusNode: _pwdNode,
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),
loading
_loading
],
),
floatingActionButton: FloatingActionButton(
tooltip: s.save,
tooltip: _s.save,
onPressed: () async {
final name = nameController.text;
final key = keyController.text.trim();
final pwd = pwdController.text;
final name = _nameController.text;
final key = _keyController.text.trim();
final pwd = _pwdController.text;
if (name.isEmpty || key.isEmpty) {
showSnackBar(context, Text(s.fieldMustNotEmpty));
showSnackBar(context, Text(_s.fieldMustNotEmpty));
return;
}
FocusScope.of(context).unfocus();
setState(() {
loading = const SizedBox(
_loading = const SizedBox(
height: 50,
child: Center(
child: CircularProgressIndicator(),
@@ -126,7 +126,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
haveErr = true;
} finally {
setState(() {
loading = const SizedBox();
_loading = const SizedBox();
});
}
if (haveErr) return;
@@ -145,9 +145,9 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
@override
void afterFirstLayout(BuildContext context) {
if (widget.info != null) {
nameController.text = widget.info!.id;
keyController.text = widget.info!.privateKey;
pwdController.text = widget.info!.password;
_nameController.text = widget.info!.id;
_keyController.text = widget.info!.privateKey;
_pwdController.text = widget.info!.password;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,8 +23,7 @@ class SFTPDownloadedPage extends StatefulWidget {
class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
PathWithPrefix? _path;
String? _prefixPath;
late S s;
late ThemeData _theme;
late S _s;
@override
void initState() {
@@ -39,15 +38,14 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
s = S.of(context);
_theme = Theme.of(context);
_s = S.of(context);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(s.download),
title: Text(_s.download),
actions: [
IconButton(
icon: const Icon(Icons.downloading),
@@ -68,7 +66,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
floatingActionButton: FloatingActionButton(
onPressed: (() {
if (_path!.path == _prefixPath) {
showSnackBar(context, Text(s.alreadyLastDir));
showSnackBar(context, Text(_s.alreadyLastDir));
return;
}
_path!.update('..');
@@ -80,18 +78,13 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
}
Widget _buildPath() {
final color = _theme.scaffoldBackgroundColor;
return Container(
color: color,
padding: const EdgeInsets.fromLTRB(11, 7, 11, 11),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Divider(),
(_path?.path ?? s.loadingFiles).omitStartStr(
style: TextStyle(
color: color.isBrightColor ? Colors.black : Colors.white),
)
(_path?.path ?? _s.loadingFiles).omitStartStr(),
],
),
);
@@ -142,30 +135,30 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
final fileName = file.path.split('/').last;
showRoundDialog(
context,
s.choose,
_s.choose,
Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: const Icon(Icons.delete),
title: Text(s.delete),
title: Text(_s.delete),
onTap: () {
Navigator.of(context).pop();
showRoundDialog(
context,
s.sureDelete(fileName),
_s.sureDelete(fileName),
const SizedBox(),
[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel)),
child: Text(_s.cancel)),
TextButton(
onPressed: () {
file.deleteSync();
setState(() {});
Navigator.of(context).pop();
},
child: Text(s.ok),
child: Text(_s.ok),
),
],
);
@@ -173,7 +166,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
),
ListTile(
leading: const Icon(Icons.open_in_new),
title: Text(s.open),
title: Text(_s.open),
onTap: () {
shareFiles(context, [file.absolute.path]);
},
@@ -183,7 +176,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
[
TextButton(
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> {
late S s;
late S _s;
@override
void didChangeDependencies() {
super.didChangeDependencies();
s = S.of(context);
_s = S.of(context);
}
@override
@@ -30,7 +30,7 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
return Scaffold(
appBar: AppBar(
title: Text(
s.download,
_s.download,
style: textSize18,
),
),
@@ -42,7 +42,7 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
return Consumer<SftpDownloadProvider>(builder: (__, pro, _) {
if (pro.status.isEmpty) {
return Center(
child: Text(s.sftpNoDownloadTask),
child: Text(_s.sftpNoDownloadTask),
);
}
return ListView.builder(
@@ -81,7 +81,7 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
final time = status.spentTime.toString();
return _wrapInCard(
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(
onPressed: () => shareFiles(context, [status.item.localPath]),
icon: const Icon(Icons.open_in_new),
@@ -90,18 +90,18 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
case SftpWorkerStatus.downloading:
return _wrapInCard(
status,
s.downloadStatus((status.progress ?? 0.0).toStringAsFixed(2),
_s.downloadStatus((status.progress ?? 0.0).toStringAsFixed(2),
(status.size ?? 0).convertBytes),
trailing:
CircularProgressIndicator(value: (status.progress ?? 0) / 100));
case SftpWorkerStatus.preparing:
return _wrapInCard(status, s.sftpDlPrepare, trailing: loadingIcon);
return _wrapInCard(status, _s.sftpDlPrepare, trailing: loadingIcon);
case SftpWorkerStatus.sshConnectted:
return _wrapInCard(status, s.sftpSSHConnected, trailing: loadingIcon);
return _wrapInCard(status, _s.sftpSSHConnected, trailing: loadingIcon);
default:
return _wrapInCard(
status,
s.unknown,
_s.unknown,
trailing: const Icon(
Icons.error,
size: 40,

View File

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

View File

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

View File

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