opt.: no app restart required
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/locale.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/ssh_client.dart';
|
||||
import 'package:toolbox/core/extension/uint8list.dart';
|
||||
@@ -25,12 +25,10 @@ import 'tag.dart';
|
||||
|
||||
class ServerFuncBtnsTopRight extends StatelessWidget {
|
||||
final ServerPrivateInfo spi;
|
||||
final S s;
|
||||
|
||||
const ServerFuncBtnsTopRight({
|
||||
super.key,
|
||||
required this.spi,
|
||||
required this.s,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -45,13 +43,13 @@ class ServerFuncBtnsTopRight extends StatelessWidget {
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(e.text(s)),
|
||||
Text(e.toStr),
|
||||
],
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
onSelected: (val) => _onTapMoreBtns(val, spi, context, s),
|
||||
onSelected: (val) => _onTapMoreBtns(val, spi, context),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -60,12 +58,10 @@ class ServerFuncBtns extends StatelessWidget {
|
||||
const ServerFuncBtns({
|
||||
super.key,
|
||||
required this.spi,
|
||||
required this.s,
|
||||
this.iconSize,
|
||||
});
|
||||
|
||||
final ServerPrivateInfo spi;
|
||||
final S s;
|
||||
final double? iconSize;
|
||||
|
||||
@override
|
||||
@@ -74,7 +70,7 @@ class ServerFuncBtns extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: ServerTabMenuType.values
|
||||
.map((e) => IconButton(
|
||||
onPressed: () => _onTapMoreBtns(e, spi, context, s),
|
||||
onPressed: () => _onTapMoreBtns(e, spi, context),
|
||||
padding: EdgeInsets.zero,
|
||||
tooltip: e.name,
|
||||
icon: Icon(e.icon, size: iconSize ?? 15),
|
||||
@@ -88,16 +84,15 @@ void _onTapMoreBtns(
|
||||
ServerTabMenuType value,
|
||||
ServerPrivateInfo spi,
|
||||
BuildContext context,
|
||||
S s,
|
||||
) async {
|
||||
switch (value) {
|
||||
case ServerTabMenuType.pkg:
|
||||
_onPkg(context, s, spi);
|
||||
_onPkg(context, spi);
|
||||
break;
|
||||
case ServerTabMenuType.sftp:
|
||||
AppRoute.sftp(spi: spi).checkGo(
|
||||
context: context,
|
||||
check: () => _checkClient(context, spi.id, s.waitConnection),
|
||||
check: () => _checkClient(context, spi.id),
|
||||
);
|
||||
break;
|
||||
case ServerTabMenuType.snippet:
|
||||
@@ -114,12 +109,12 @@ void _onTapMoreBtns(
|
||||
final result = await Providers.server.runSnippets(spi.id, snippets);
|
||||
if (result != null && result.isNotEmpty) {
|
||||
context.showRoundDialog(
|
||||
title: Text(s.result),
|
||||
title: Text(l10n.result),
|
||||
child: Text(result),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => copy2Clipboard(result),
|
||||
child: Text(s.copy),
|
||||
child: Text(l10n.copy),
|
||||
)
|
||||
],
|
||||
);
|
||||
@@ -128,13 +123,13 @@ void _onTapMoreBtns(
|
||||
case ServerTabMenuType.docker:
|
||||
AppRoute.docker(spi: spi).checkGo(
|
||||
context: context,
|
||||
check: () => _checkClient(context, spi.id, s.waitConnection),
|
||||
check: () => _checkClient(context, spi.id),
|
||||
);
|
||||
break;
|
||||
case ServerTabMenuType.process:
|
||||
AppRoute.process(spi: spi).checkGo(
|
||||
context: context,
|
||||
check: () => _checkClient(context, spi.id, s.waitConnection),
|
||||
check: () => _checkClient(context, spi.id),
|
||||
);
|
||||
break;
|
||||
case ServerTabMenuType.terminal:
|
||||
@@ -192,19 +187,19 @@ Future<void> _gotoSSH(
|
||||
}
|
||||
}
|
||||
|
||||
bool _checkClient(BuildContext context, String id, String msg) {
|
||||
bool _checkClient(BuildContext context, String id) {
|
||||
final server = Providers.server.servers[id];
|
||||
if (server == null || server.client == null) {
|
||||
context.showSnackBar(msg);
|
||||
context.showSnackBar(l10n.waitConnection);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> _onPkg(BuildContext context, S s, ServerPrivateInfo spi) async {
|
||||
Future<void> _onPkg(BuildContext context, ServerPrivateInfo spi) async {
|
||||
final server = spi.findServer;
|
||||
if (server == null) {
|
||||
context.showSnackBar(s.noClient);
|
||||
context.showSnackBar(l10n.noClient);
|
||||
return;
|
||||
}
|
||||
final sys = server.status.sysVer;
|
||||
@@ -232,13 +227,13 @@ Future<void> _onPkg(BuildContext context, S s, ServerPrivateInfo spi) async {
|
||||
final result = await server.client?.run(listCmd).string;
|
||||
context.pop();
|
||||
if (result == null) {
|
||||
context.showSnackBar(s.noResult);
|
||||
context.showSnackBar(l10n.noResult);
|
||||
return;
|
||||
}
|
||||
final list = pkg?.updateListRemoveUnused(result.split('\n'));
|
||||
final upgradeable = list?.map((e) => UpgradePkgInfo(e, pkg)).toList();
|
||||
if (upgradeable == null || upgradeable.isEmpty) {
|
||||
context.showSnackBar(s.noUpdateAvailable);
|
||||
context.showSnackBar(l10n.noUpdateAvailable);
|
||||
return;
|
||||
}
|
||||
final args = upgradeable.map((e) => e.package).join(' ');
|
||||
@@ -247,14 +242,14 @@ Future<void> _onPkg(BuildContext context, S s, ServerPrivateInfo spi) async {
|
||||
|
||||
// Confirm upgrade
|
||||
final gotoUpgrade = await context.showRoundDialog<bool>(
|
||||
title: Text(s.attention),
|
||||
title: Text(l10n.attention),
|
||||
child: SingleChildScrollView(
|
||||
child: Text('${s.foundNUpdate(upgradeable.length)}\n\n$upgradeCmd'),
|
||||
child: Text('${l10n.foundNUpdate(upgradeable.length)}\n\n$upgradeCmd'),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(true),
|
||||
child: Text(s.update),
|
||||
child: Text(l10n.update),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -263,6 +258,6 @@ Future<void> _onPkg(BuildContext context, S s, ServerPrivateInfo spi) async {
|
||||
|
||||
AppRoute.ssh(spi: spi, initCmd: upgradeCmd).checkGo(
|
||||
context: context,
|
||||
check: () => _checkClient(context, spi.id, s.waitConnection),
|
||||
check: () => _checkClient(context, spi.id),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/locale.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import '../../data/model/app/tag_pickable.dart';
|
||||
import '../../data/res/color.dart';
|
||||
@@ -39,7 +39,6 @@ class TagBtn extends StatelessWidget {
|
||||
|
||||
class TagEditor extends StatefulWidget {
|
||||
final List<String> tags;
|
||||
final S s;
|
||||
final void Function(List<String>)? onChanged;
|
||||
final void Function(String old, String new_)? onRenameTag;
|
||||
final List<String> allTags;
|
||||
@@ -47,7 +46,6 @@ class TagEditor extends StatefulWidget {
|
||||
const TagEditor({
|
||||
super.key,
|
||||
required this.tags,
|
||||
required this.s,
|
||||
this.onChanged,
|
||||
this.onRenameTag,
|
||||
this.allTags = const <String>[],
|
||||
@@ -78,7 +76,7 @@ class _TagEditorState extends State<TagEditor> {
|
||||
|
||||
/// Add vertical divider if suggestions.length > 0
|
||||
final counts = tags.length + suggestionLen + (suggestionLen == 0 ? 0 : 1);
|
||||
if (counts == 0) return Text(widget.s.tag);
|
||||
if (counts == 0) return Text(l10n.tag);
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: _kTagBtnHeight),
|
||||
child: ListView.builder(
|
||||
@@ -134,12 +132,12 @@ class _TagEditorState extends State<TagEditor> {
|
||||
void _showAddTagDialog() {
|
||||
final textEditingController = TextEditingController();
|
||||
context.showRoundDialog(
|
||||
title: Text(widget.s.add),
|
||||
title: Text(l10n.add),
|
||||
child: Input(
|
||||
autoFocus: true,
|
||||
icon: Icons.tag,
|
||||
controller: textEditingController,
|
||||
hint: widget.s.tag,
|
||||
hint: l10n.tag,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -149,7 +147,7 @@ class _TagEditorState extends State<TagEditor> {
|
||||
widget.onChanged?.call(widget.tags);
|
||||
context.pop();
|
||||
},
|
||||
child: Text(widget.s.add),
|
||||
child: Text(l10n.add),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -158,12 +156,12 @@ class _TagEditorState extends State<TagEditor> {
|
||||
void _showRenameDialog(String tag) {
|
||||
final textEditingController = TextEditingController(text: tag);
|
||||
context.showRoundDialog(
|
||||
title: Text(widget.s.rename),
|
||||
title: Text(l10n.rename),
|
||||
child: Input(
|
||||
autoFocus: true,
|
||||
icon: Icons.abc,
|
||||
controller: textEditingController,
|
||||
hint: widget.s.tag,
|
||||
hint: l10n.tag,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -174,7 +172,7 @@ class _TagEditorState extends State<TagEditor> {
|
||||
context.pop();
|
||||
setState(() {});
|
||||
},
|
||||
child: Text(widget.s.rename),
|
||||
child: Text(l10n.rename),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -196,14 +194,12 @@ class TagPicker<T extends TagPickable> extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
|
||||
late S _s;
|
||||
late MediaQueryData _media;
|
||||
final List<T> _selected = [];
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_s = S.of(context)!;
|
||||
_media = MediaQuery.of(context);
|
||||
}
|
||||
|
||||
@@ -211,7 +207,7 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
|
||||
Widget build(BuildContext context) {
|
||||
final children = <Widget>[];
|
||||
if (widget.tags.isNotEmpty) {
|
||||
children.add(Text(_s.tag));
|
||||
children.add(Text(l10n.tag));
|
||||
children.add(UIs.height13);
|
||||
children.add(SizedBox(
|
||||
height: _kTagBtnHeight,
|
||||
@@ -220,7 +216,7 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
|
||||
));
|
||||
}
|
||||
if (widget.items.isNotEmpty) {
|
||||
children.add(Text(_s.all));
|
||||
children.add(Text(l10n.all));
|
||||
children.add(UIs.height13);
|
||||
children.add(SizedBox(
|
||||
height: _kTagBtnHeight,
|
||||
@@ -229,15 +225,15 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
|
||||
));
|
||||
}
|
||||
final child = widget.tags.isEmpty && widget.items.isEmpty
|
||||
? Text(_s.noOptions)
|
||||
? Text(l10n.noOptions)
|
||||
: Column(mainAxisSize: MainAxisSize.min, children: children);
|
||||
return AlertDialog(
|
||||
title: Text(_s.choose),
|
||||
title: Text(l10n.choose),
|
||||
content: child,
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(_selected),
|
||||
child: Text(_s.ok),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user