mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-18 07:44:26 +01:00
new: pick dialog support tags
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/locale.dart';
|
||||
import 'package:toolbox/view/widget/choice_chip.dart';
|
||||
import 'package:toolbox/view/widget/tag.dart';
|
||||
|
||||
import '../../../data/res/ui.dart';
|
||||
import '../../../view/widget/input_field.dart';
|
||||
@@ -119,4 +120,77 @@ extension DialogX on BuildContext {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<List<T>?> showPickWithTagDialog<T>({
|
||||
required List<T?> Function(String? tag) itemsBuilder,
|
||||
required ValueNotifier<List<String>> tags,
|
||||
String Function(T)? name,
|
||||
List<T>? initial,
|
||||
bool clearable = false,
|
||||
bool multi = false,
|
||||
List<Widget>? actions,
|
||||
}) async {
|
||||
var vals = initial ?? <T>[];
|
||||
final tag = ValueNotifier<String?>(null);
|
||||
final sure = await showRoundDialog<bool>(
|
||||
title: Text(l10n.choose),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ListenableBuilder(
|
||||
listenable: tag,
|
||||
builder: (_, __) => TagSwitcher(
|
||||
tags: tags,
|
||||
width: 300,
|
||||
initTag: tag.value,
|
||||
onTagChanged: (e) => tag.value = e,
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
SingleChildScrollView(
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: tag,
|
||||
builder: (_, val, __) {
|
||||
final items = itemsBuilder(val);
|
||||
return Choice<T>(
|
||||
onChanged: (value) => vals = value,
|
||||
multiple: multi,
|
||||
clearable: clearable,
|
||||
value: vals,
|
||||
builder: (state, _) {
|
||||
return Wrap(
|
||||
children: List<Widget>.generate(
|
||||
items.length,
|
||||
(index) {
|
||||
final item = items[index];
|
||||
if (item == null) return UIs.placeholder;
|
||||
return ChoiceChipX<T>(
|
||||
label: name?.call(item) ?? item.toString(),
|
||||
state: state,
|
||||
value: item,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
if (actions != null) ...actions,
|
||||
TextButton(
|
||||
onPressed: () => pop(true),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
if (sure == true && vals.isNotEmpty) {
|
||||
return vals;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 770;
|
||||
static const int build = 771;
|
||||
static const String engine = "3.19.0";
|
||||
static const String buildAt = "2024-02-20 15:34:30";
|
||||
static const int modifications = 10;
|
||||
static const String buildAt = "2024-02-20 16:12:21";
|
||||
static const int modifications = 8;
|
||||
static const int script = 38;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,6 @@ class _ServerPageState extends State<ServerPage>
|
||||
_tag = p0;
|
||||
}),
|
||||
initTag: _tag,
|
||||
all: l10n.all,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ class _SnippetListPageState extends State<SnippetListPage> {
|
||||
tags: provider.tags,
|
||||
onTagChanged: (tag) => setState(() => _tag = tag),
|
||||
initTag: _tag,
|
||||
all: l10n.all,
|
||||
width: _media.size.width,
|
||||
),
|
||||
footer: UIs.height77,
|
||||
|
||||
@@ -275,12 +275,20 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
|
||||
}
|
||||
break;
|
||||
case VirtualKeyFunc.snippet:
|
||||
final s = await context.showPickSingleDialog<Snippet>(
|
||||
items: Pros.snippet.snippets,
|
||||
name: (p0) => p0.name,
|
||||
final snippets = await context.showPickWithTagDialog<Snippet>(
|
||||
tags: Pros.snippet.tags,
|
||||
itemsBuilder: (e) {
|
||||
if (e == null) return Pros.snippet.snippets;
|
||||
return Pros.snippet.snippets
|
||||
.where((element) => element.tags?.contains(e) ?? false)
|
||||
.toList();
|
||||
},
|
||||
name: (e) => e.name,
|
||||
);
|
||||
if (s == null) return;
|
||||
_terminal.textInput(s.script);
|
||||
if (snippets == null || snippets.isEmpty) return;
|
||||
|
||||
final snippet = snippets.first;
|
||||
_terminal.textInput(snippet.script);
|
||||
_terminal.keyInput(TerminalKey.enter);
|
||||
break;
|
||||
case VirtualKeyFunc.file:
|
||||
|
||||
@@ -122,11 +122,18 @@ void _onTapMoreBtns(
|
||||
);
|
||||
break;
|
||||
case ServerFuncBtn.snippet:
|
||||
final snippet = await context.showPickSingleDialog<Snippet>(
|
||||
items: Pros.snippet.snippets,
|
||||
final snippets = await context.showPickWithTagDialog<Snippet>(
|
||||
tags: Pros.snippet.tags,
|
||||
itemsBuilder: (e) {
|
||||
if (e == null) return Pros.snippet.snippets;
|
||||
return Pros.snippet.snippets
|
||||
.where((element) => element.tags?.contains(e) ?? false)
|
||||
.toList();
|
||||
},
|
||||
name: (e) => e.name,
|
||||
);
|
||||
if (snippet == null) return;
|
||||
if (snippets == null || snippets.isEmpty) return;
|
||||
final snippet = snippets.first;
|
||||
|
||||
AppRoute.ssh(spi: spi, initCmd: snippet.fmtWith(spi)).checkGo(
|
||||
context: context,
|
||||
|
||||
@@ -184,14 +184,12 @@ class TagSwitcher extends StatelessWidget implements PreferredSizeWidget {
|
||||
final double width;
|
||||
final void Function(String?) onTagChanged;
|
||||
final String? initTag;
|
||||
final String all;
|
||||
|
||||
const TagSwitcher({
|
||||
super.key,
|
||||
required this.tags,
|
||||
required this.width,
|
||||
required this.onTagChanged,
|
||||
required this.all,
|
||||
this.initTag,
|
||||
});
|
||||
|
||||
@@ -213,7 +211,7 @@ class TagSwitcher extends StatelessWidget implements PreferredSizeWidget {
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
return TagBtn(
|
||||
content: item == null ? all : '#$item',
|
||||
content: item == null ? l10n.all : '#$item',
|
||||
isEnable: initTag == item,
|
||||
onTap: () => onTagChanged(item),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user