diff --git a/README.md b/README.md index f446b9ea..b0966aca 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/rel ## 🔖 Feature - `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Process`... - Platform specific: `Bio auth`、`Msg push`、`Home widget`、`watchOS App`... -- English, 简体中文; Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic); Español, Русский язык, Português, 日本語 (Generated by GPT) +- English, 简体中文; Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic), Türkçe [@mikropsoft](https://github.com/mikropsoft); Español, Русский язык, Português, 日本語 (Generated by GPT) ## 🏙️ ScreenShots diff --git a/README_zh.md b/README_zh.md index 55430729..c0078197 100644 --- a/README_zh.md +++ b/README_zh.md @@ -33,7 +33,7 @@ Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/rel - 本地化 - English, 简体中文 - Español, Русский язык, Português, 日本語 (Generated by GPT) - - Deutsch (@its-tom) / 繁體中文 (@kalashnikov) / Indonesian (@azkadev) / Français (@FrancXPT) / Dutch (@QazCetelic) + - Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic), Türkçe [@mikropsoft](https://github.com/mikropsoft); ## 🏙️ 截屏 diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 524419d7..2f5259f4 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -26,8 +26,8 @@ class ServerProvider extends ChangeNotifier { Iterable get servers => _servers.values; final List _serverOrder = []; List get serverOrder => _serverOrder; - final _tags = ValueNotifier([]); - ValueNotifier> get tags => _tags; + final _tags = ValueNotifier({}); + ValueNotifier> get tags => _tags; Timer? _timer; @@ -85,7 +85,6 @@ class ServerProvider extends ChangeNotifier { } void _updateTags() { - _tags.value.clear(); for (final s in _servers.values) { if (s.spi.tags == null) continue; for (final t in s.spi.tags!) { @@ -94,21 +93,7 @@ class ServerProvider extends ChangeNotifier { } } } - _tags.value.sort(); - _tags.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_; - } - } - Stores.server.update(s.spi, s.spi); - } - _updateTags(); + _tags.value = (_tags.value.toList()..sort()).toSet(); } Server genServer(ServerPrivateInfo spi) { diff --git a/lib/data/provider/snippet.dart b/lib/data/provider/snippet.dart index aea31db6..914b639a 100644 --- a/lib/data/provider/snippet.dart +++ b/lib/data/provider/snippet.dart @@ -9,8 +9,7 @@ class SnippetProvider extends ChangeNotifier { late List _snippets; List get snippets => _snippets; - final _tags = ValueNotifier([]); - ValueNotifier> get tags => _tags; + final tags = ValueNotifier({}); void load() { _snippets = Stores.snippet.fetch(); @@ -29,16 +28,14 @@ class SnippetProvider extends ChangeNotifier { } void _updateTags() { - _tags.value.clear(); - final tags = {}; + final tags_ = {}; for (final s in _snippets) { - if (s.tags?.isEmpty ?? true) { - continue; + final t = s.tags; + if (t != null) { + tags_.addAll(t); } - tags.addAll(s.tags!); } - _tags.value.addAll(tags); - _tags.notifyListeners(); + tags.value = tags_; } void add(Snippet snippet) { diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index 0bf5791d..899dd73f 100644 --- a/lib/view/page/server/edit.dart +++ b/lib/view/page/server/edit.dart @@ -48,8 +48,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { final _pveIgnoreCert = ValueNotifier(false); final _env = {}.vn; final _customCmds = {}.vn; - - var _tags = []; + final _tags = {}.vn; @override void dispose() { @@ -170,12 +169,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { hint: 'root', suggestion: false, ), - TagEditor( - tags: _tags, - onChanged: (p0) => _tags = p0, - allTags: [...Pros.server.tags.value], - onRenameTag: Pros.server.renameTag, - ), + TagTile(tags: _tags, allTags: Pros.server.tags.value).cardx, ListTile( title: Text(l10n.autoConnect), trailing: ListenableBuilder( @@ -436,7 +430,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { List _buildWOLs() { return [ - const Text('Wake On LAN', style: UIs.text13Grey), + const Text('Wake On LAN (beta)', style: UIs.text13Grey), UIs.height7, ListTile( leading: const Icon(BoxIcons.bxs_help_circle), @@ -455,7 +449,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { controller: _wolIpCtrl, type: TextInputType.text, label: 'IP ${l10n.addr}', - icon: Icons.network_cell, + icon: ZondIcons.network, hint: '192.168.1.x', suggestion: false, ), @@ -590,7 +584,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { keyId: _keyIdx.value != null ? Pros.key.pkis.elementAt(_keyIdx.value!).id : null, - tags: _tags, + tags: _tags.value.isEmpty ? null : _tags.value.toList(), alterUrl: _altUrlController.text.selfIfNotNullEmpty, autoConnect: _autoConnect.value, jumpId: _jumpServer.value, @@ -616,7 +610,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { context.showRoundDialog( title: l10n.attention, child: SimpleMarkdown(data: l10n.writeScriptTip), - actions: Btns.oks(onTap: () => context.pop(true)), + actions: [Btn.ok()], ); }, child: Row( @@ -648,7 +642,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { } /// List in dart is passed by pointer, so you need to copy it here - _tags.addAll(spi.tags ?? []); + _tags.value = spi.tags?.toSet() ?? {}; _altUrlController.text = spi.alterUrl ?? ''; _autoConnect.value = spi.autoConnect ?? true; diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 6e940561..170d971a 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -1251,7 +1251,8 @@ class _SettingPageState extends State { ), onTap: () async { final ctrl = TextEditingController(text: val); - void onSave(String s) { + void onSave() { + final s = ctrl.text.trim(); _setting.sftpEditor.put(s); context.pop(); } @@ -1265,9 +1266,9 @@ class _SettingPageState extends State { hint: '\$EDITOR / vim / nano ...', icon: Icons.edit, suggestion: false, - onSubmitted: onSave, + onSubmitted: (_) => onSave(), ), - actions: Btns.oks(onTap: () => onSave(ctrl.text)), + actions: [Btn.ok(onTap: (_) => onSave())], ); }, ); diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index 8b5d21d6..8055cd2e 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -2,10 +2,9 @@ import 'package:fl_lib/fl_lib.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:server_box/core/extension/context/locale.dart'; +import 'package:server_box/data/model/server/snippet.dart'; import 'package:server_box/data/res/provider.dart'; -import '../../../data/model/server/snippet.dart'; - class SnippetEditPage extends StatefulWidget { const SnippetEditPage({super.key, this.snippet}); @@ -22,7 +21,7 @@ class _SnippetEditPageState extends State final _noteController = TextEditingController(); final _scriptNode = FocusNode(); final _autoRunOn = ValueNotifier([]); - final _tags = ValueNotifier([]); + final _tags = {}.vn; @override void dispose() { @@ -36,7 +35,7 @@ class _SnippetEditPageState extends State Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( - title: Text(l10n.edit, style: UIs.text18), + title: Text(l10n.edit), actions: _buildAppBarActions(), ), body: _buildBody(), @@ -45,9 +44,7 @@ class _SnippetEditPageState extends State } List? _buildAppBarActions() { - if (widget.snippet == null) { - return null; - } + if (widget.snippet == null) return null; return [ IconButton( onPressed: () { @@ -89,7 +86,7 @@ class _SnippetEditPageState extends State final snippet = Snippet( name: name, script: script, - tags: _tags.value.isEmpty ? null : _tags.value, + tags: _tags.value.isEmpty ? null : _tags.value.toList(), note: note.isEmpty ? null : note, autoRunOn: _autoRunOn.value.isEmpty ? null : _autoRunOn.value, ); @@ -125,21 +122,7 @@ class _SnippetEditPageState extends State icon: Icons.note, suggestion: true, ), - ValBuilder( - listenable: _tags, - builder: (vals) { - return TagEditor( - tags: _tags.value, - onChanged: (p0) => setState(() { - _tags.value = p0; - }), - allTags: [...Pros.snippet.tags.value], - onRenameTag: (old, n) => setState(() { - Pros.snippet.renameTag(old, n); - }), - ); - }, - ), + TagTile(tags: _tags, allTags: Pros.snippet.tags.value).cardx, Input( controller: _scriptController, node: _scriptNode, @@ -167,7 +150,10 @@ class _SnippetEditPageState extends State .map((e) => Pros.server.pick(id: e)?.spi.name ?? e) .join(', '); return ListTile( - leading: const Icon(Icons.settings_remote, size: 19), + leading: const Padding( + padding: EdgeInsets.only(left: 5), + child: Icon(Icons.settings_remote, size: 19), + ), title: Text(l10n.autoRun), trailing: const Icon(Icons.keyboard_arrow_right), subtitle: subtitle == null @@ -232,7 +218,7 @@ ${l10n.forExample}: } if (snippet.tags != null) { - _tags.value = snippet.tags!; + _tags.value = snippet.tags!.toSet(); } if (snippet.autoRunOn != null) { diff --git a/lib/view/page/snippet/list.dart b/lib/view/page/snippet/list.dart index 7dcc6c91..a4025048 100644 --- a/lib/view/page/snippet/list.dart +++ b/lib/view/page/snippet/list.dart @@ -100,16 +100,8 @@ class _SnippetListPageState extends State { maxLines: 3, style: UIs.textGrey, ), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - onPressed: () => - AppRoutes.snippetEdit(snippet: snippet).go(context), - icon: const Icon(Icons.edit), - ), - ], - ), + trailing: const Icon(Icons.keyboard_arrow_right), + onTap: () => AppRoutes.snippetEdit(snippet: snippet).go(context), ), ); } diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index 0f3ca6aa..f20e2a8f 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -396,7 +396,7 @@ class _SftpPageState extends State with AfterLayoutMixin { var newPerm = perm.copyWith(); final ok = await context.showRoundDialog( child: UnixPermEditor(perm: perm, onChanged: (p) => newPerm = p), - actions: Btns.oks(onTap: () => context.pop(true)), + actions: [Btn.ok(onTap: (context) => context.pop(true))], ); final permStr = newPerm.perm; @@ -752,7 +752,7 @@ class _SftpPageState extends State with AfterLayoutMixin { context.showRoundDialog( title: l10n.error, child: Text('Unsupport file: ${name.filename}'), - actions: Btns.oks(onTap: () => context.pop()), + actions: [Btn.ok()], ); return; } @@ -760,11 +760,10 @@ class _SftpPageState extends State with AfterLayoutMixin { final confirm = await context.showRoundDialog( title: l10n.attention, child: SimpleMarkdown(data: '```sh\n$cmd\n```'), - actions: Btns.okCancels( - onTapOk: () => context.pop(true), - onTapCancel: () => context.pop(false), - red: true, - ), + actions: [ + Btn.cancel(onTap: (c) => c.pop(false)), + Btn.ok(onTap: (c) => c.pop(true), red: true), + ], ); if (confirm != true) return; diff --git a/pubspec.lock b/pubspec.lock index 16a11647..4c0b082a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -385,8 +385,8 @@ packages: dependency: "direct main" description: path: "." - ref: "v1.0.90" - resolved-ref: "9f17bfce9f6cc9e071c40648bcac8d94e2dee919" + ref: "v1.0.94" + resolved-ref: b4e431b7131605fa266be80a016165562b5437eb url: "https://github.com/lppcg/fl_lib" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index 51afb46b..182b9a7a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,7 +62,7 @@ dependencies: fl_lib: git: url: https://github.com/lppcg/fl_lib - ref: v1.0.90 + ref: v1.0.94 dependency_overrides: # dartssh2: