mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 15:24:35 +01:00
new: tag rename
This commit is contained in:
@@ -77,6 +77,19 @@ class ServerProvider extends BusyProvider {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void renameTag(String old, String new_) {
|
||||
for (final s in _servers.values) {
|
||||
if (s.spi.tags == null) continue;
|
||||
for (var i = 0; i < s.spi.tags!.length; i++) {
|
||||
if (s.spi.tags![i] == old) {
|
||||
s.spi.tags![i] = new_;
|
||||
}
|
||||
}
|
||||
_serverStore.update(s.spi, s.spi);
|
||||
}
|
||||
_updateTags();
|
||||
}
|
||||
|
||||
Server genServer(ServerPrivateInfo spi) {
|
||||
return Server(spi, initStatus, null, ServerState.disconnected);
|
||||
}
|
||||
|
||||
29
lib/data/res/default.dart
Normal file
29
lib/data/res/default.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'dart:ui';
|
||||
|
||||
// default server details page cards order
|
||||
const defaultDetailCardOrder = [
|
||||
'uptime',
|
||||
'cpu',
|
||||
'mem',
|
||||
'swap',
|
||||
'disk',
|
||||
'net',
|
||||
'temp'
|
||||
];
|
||||
|
||||
const defaultDiskIgnorePath = [
|
||||
'udev',
|
||||
'tmpfs',
|
||||
'devtmpfs',
|
||||
'overlay',
|
||||
'run',
|
||||
'none',
|
||||
];
|
||||
|
||||
const defaultPrimaryColor = Color.fromARGB(255, 145, 58, 31);
|
||||
|
||||
const defaultLaunchPageIdx = 0;
|
||||
|
||||
const defaultUpdateInterval = 3;
|
||||
|
||||
const defaultEditorTheme = 'monokai';
|
||||
@@ -15,14 +15,3 @@ const maxDebugLogLines = 100;
|
||||
/// Method Channels
|
||||
const pkgName = 'tech.lolli.toolbox';
|
||||
const bgRunChannel = MethodChannel('$pkgName/app_retain');
|
||||
|
||||
// default server details page cards order
|
||||
const defaultDetailCardOrder = [
|
||||
'uptime',
|
||||
'cpu',
|
||||
'mem',
|
||||
'swap',
|
||||
'disk',
|
||||
'net',
|
||||
'temp'
|
||||
];
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/core/persistant_store.dart';
|
||||
import 'package:toolbox/core/utils/platform.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
|
||||
import '../res/default.dart';
|
||||
|
||||
class SettingStore extends PersistentStore {
|
||||
StoreProperty<int> get primaryColor => property(
|
||||
'primaryColor',
|
||||
defaultValue: const Color.fromARGB(255, 145, 58, 31).value,
|
||||
defaultValue: defaultPrimaryColor.value,
|
||||
);
|
||||
|
||||
StoreProperty<int> get serverStatusUpdateInterval =>
|
||||
property('serverStatusUpdateInterval', defaultValue: 3);
|
||||
property('serverStatusUpdateInterval', defaultValue: defaultUpdateInterval,);
|
||||
|
||||
// Lanch page idx
|
||||
StoreProperty<int> get launchPage => property('launchPage', defaultValue: 0);
|
||||
StoreProperty<int> get launchPage => property('launchPage', defaultValue: defaultLaunchPageIdx,);
|
||||
|
||||
// Version of store db
|
||||
StoreProperty<int> get storeVersion =>
|
||||
@@ -57,14 +57,7 @@ class SettingStore extends PersistentStore {
|
||||
|
||||
// Server detail disk ignore path
|
||||
StoreProperty<List<String>> get diskIgnorePath =>
|
||||
property('diskIgnorePath', defaultValue: [
|
||||
'udev',
|
||||
'tmpfs',
|
||||
'devtmpfs',
|
||||
'overlay',
|
||||
'run',
|
||||
'none',
|
||||
]);
|
||||
property('diskIgnorePath', defaultValue: defaultDiskIgnorePath);
|
||||
|
||||
// Locale
|
||||
StoreProperty<String> get locale => property('locale', defaultValue: null);
|
||||
@@ -75,5 +68,5 @@ class SettingStore extends PersistentStore {
|
||||
|
||||
// Editor theme
|
||||
StoreProperty<String> get editorTheme =>
|
||||
property('editorTheme', defaultValue: 'monokai');
|
||||
property('editorTheme', defaultValue: defaultEditorTheme);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ class _PingPageState extends State<PingPage>
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
heroTag: 'ping',
|
||||
onPressed: () {
|
||||
try {
|
||||
doPing();
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:toolbox/data/model/server/disk.dart';
|
||||
import 'package:toolbox/data/model/server/dist.dart';
|
||||
import 'package:toolbox/data/model/server/memory.dart';
|
||||
import 'package:toolbox/data/model/server/temp.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
|
||||
import '../../../core/extension/numx.dart';
|
||||
import '../../../data/model/server/net_speed.dart';
|
||||
@@ -15,6 +14,7 @@ import '../../../data/model/server/server.dart';
|
||||
import '../../../data/model/server/server_status.dart';
|
||||
import '../../../data/provider/server.dart';
|
||||
import '../../../data/res/color.dart';
|
||||
import '../../../data/res/default.dart';
|
||||
import '../../../data/res/ui.dart';
|
||||
import '../../../data/store/setting.dart';
|
||||
import '../../../locator.dart';
|
||||
|
||||
@@ -153,6 +153,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
|
||||
}),
|
||||
s: _s,
|
||||
tagSuggestions: [..._serverProvider.tags],
|
||||
onRenameTag: _serverProvider.renameTag,
|
||||
),
|
||||
width7,
|
||||
Row(
|
||||
@@ -225,6 +226,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
|
||||
|
||||
Widget _buildFAB() {
|
||||
return FloatingActionButton(
|
||||
heroTag: 'server',
|
||||
child: const Icon(Icons.send),
|
||||
onPressed: () async {
|
||||
if (_ipController.text == '') {
|
||||
|
||||
@@ -74,6 +74,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
'Add server info page',
|
||||
).go(context),
|
||||
tooltip: _s.addAServer,
|
||||
heroTag: 'server',
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -65,6 +65,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
|
||||
|
||||
Widget _buildFAB() {
|
||||
return FloatingActionButton(
|
||||
heroTag: 'snippet',
|
||||
child: const Icon(Icons.send),
|
||||
onPressed: () {
|
||||
final name = _nameController.text;
|
||||
|
||||
@@ -28,9 +28,10 @@ class _SnippetListPageState extends State<SnippetListPage> {
|
||||
return Scaffold(
|
||||
body: _buildBody(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
heroTag: 'snippet',
|
||||
child: const Icon(Icons.add),
|
||||
onPressed: () =>
|
||||
AppRoute(const SnippetEditPage(), 'snippet edit page').go(context),
|
||||
AppRoute(const SnippetEditPage(), 'snippet edit page',).go(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/core/extension/navigator.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';
|
||||
@@ -10,7 +11,7 @@ class TagEditor extends StatelessWidget {
|
||||
final List<String> tags;
|
||||
final S s;
|
||||
final void Function(List<String>)? onChanged;
|
||||
final void Function(String)? onTapTag;
|
||||
final void Function(String old, String new_)? onRenameTag;
|
||||
final List<String>? tagSuggestions;
|
||||
|
||||
const TagEditor({
|
||||
@@ -18,7 +19,7 @@ class TagEditor extends StatelessWidget {
|
||||
required this.tags,
|
||||
required this.s,
|
||||
this.onChanged,
|
||||
this.onTapTag,
|
||||
this.onRenameTag,
|
||||
this.tagSuggestions,
|
||||
});
|
||||
|
||||
@@ -26,7 +27,7 @@ class TagEditor extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return RoundRectCard(ListTile(
|
||||
leading: const Icon(Icons.tag),
|
||||
title: _buildTags(tags),
|
||||
title: _buildTags(context, tags),
|
||||
trailing: InkWell(
|
||||
child: const Icon(Icons.add),
|
||||
onTap: () {
|
||||
@@ -36,30 +37,34 @@ class TagEditor extends StatelessWidget {
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildTags(List<String> tags) {
|
||||
Widget _buildTags(BuildContext context, List<String> tags) {
|
||||
tagSuggestions?.removeWhere((element) => tags.contains(element));
|
||||
final suggestionLen = tagSuggestions?.length ?? 0;
|
||||
final counts = tags.length + suggestionLen + (suggestionLen == 0 ? 0 : 1);
|
||||
if (counts == 0) return Text(s.tag);
|
||||
return ConstrainedBox(constraints: BoxConstraints(maxHeight: 27), child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (context, index) {
|
||||
if (index < tags.length) {
|
||||
return _buildTagItem(tags[index], false);
|
||||
} else if (index > tags.length) {
|
||||
return _buildTagItem(tagSuggestions![index - tags.length - 1], true);
|
||||
}
|
||||
return const VerticalDivider();
|
||||
},
|
||||
itemCount: counts,
|
||||
),);
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 27),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (context, index) {
|
||||
if (index < tags.length) {
|
||||
return _buildTagItem(context, tags[index], false);
|
||||
} else if (index > tags.length) {
|
||||
return _buildTagItem(context,
|
||||
tagSuggestions![index - tags.length - 1], true,);
|
||||
}
|
||||
return const VerticalDivider();
|
||||
},
|
||||
itemCount: counts,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTagItem(String tag, bool isAdd) {
|
||||
Widget _buildTagItem(BuildContext context, String tag, bool isAdd) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||
child: GestureDetector(
|
||||
onTap: () => onTapTag?.call(tag),
|
||||
onTap: () => _showRenameDialog(context, tag),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20.0)),
|
||||
@@ -122,4 +127,27 @@ class TagEditor extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _showRenameDialog(BuildContext context, String tag) {
|
||||
final textEditingController = TextEditingController(text: tag);
|
||||
showRoundDialog(
|
||||
context: context,
|
||||
title: Text(s.rename),
|
||||
child: Input(
|
||||
controller: textEditingController,
|
||||
hint: s.tag,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final newTag = textEditingController.text.trim();
|
||||
if (newTag.isEmpty) return;
|
||||
onRenameTag?.call(tag, newTag);
|
||||
context.pop();
|
||||
},
|
||||
child: Text(s.rename),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user