From e3f2b211a97fe88ac584b36dfc3e8c76abf80309 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Mon, 21 Aug 2023 13:54:09 +0800 Subject: [PATCH] new & opt. opt.: input field auto focus opt.: snippet page top padding new: setting of editor font size --- lib/data/res/ui.dart | 1 + lib/data/store/setting.dart | 3 + lib/view/page/docker.dart | 1 + lib/view/page/editor.dart | 3 + lib/view/page/ping.dart | 1 + lib/view/page/pkg.dart | 1 + lib/view/page/private_key/edit.dart | 1 + lib/view/page/server/edit.dart | 1 + lib/view/page/server/tab.dart | 5 +- lib/view/page/setting/entry.dart | 102 ++++++++++++++++++---------- lib/view/page/snippet/edit.dart | 1 + lib/view/page/snippet/list.dart | 3 +- lib/view/page/storage/local.dart | 1 + lib/view/page/storage/sftp.dart | 8 +++ lib/view/widget/input_field.dart | 5 +- lib/view/widget/tag.dart | 12 ++-- 16 files changed, 106 insertions(+), 43 deletions(-) diff --git a/lib/data/res/ui.dart b/lib/data/res/ui.dart index 0411478a..ae1b3145 100644 --- a/lib/data/res/ui.dart +++ b/lib/data/res/ui.dart @@ -27,6 +27,7 @@ const roundRectCardPadding = EdgeInsets.symmetric(horizontal: 17, vertical: 13); const placeholder = SizedBox(); const height13 = SizedBox(height: 13); +const height77 = SizedBox(height: 77); const width13 = SizedBox(width: 13); const width7 = SizedBox(width: 7); diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 38e0c90e..db70631f 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -71,6 +71,9 @@ class SettingStore extends PersistentStore { StoreProperty get sshVirtualKeyAutoOff => property('sshVirtualKeyAutoOff', defaultValue: true); + StoreProperty get editorFontSize => + property('editorFontSize', defaultValue: 13); + // Editor theme StoreProperty get editorTheme => property('editorTheme', defaultValue: defaultEditorTheme); diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index d8f4bdba..bb18474e 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -103,6 +103,7 @@ class _DockerManagePageState extends State { mainAxisSize: MainAxisSize.min, children: [ Input( + autoFocus: true, type: TextInputType.text, label: _s.image, hint: 'xxx:1.1', diff --git a/lib/view/page/editor.dart b/lib/view/page/editor.dart index 48e26104..d9e472f3 100644 --- a/lib/view/page/editor.dart +++ b/lib/view/page/editor.dart @@ -33,6 +33,7 @@ class _EditorPageState extends State with AfterLayoutMixin { Map? _codeTheme; late S _s; late String? _langCode; + late TextStyle _textStyle; @override void initState() { @@ -41,6 +42,7 @@ class _EditorPageState extends State with AfterLayoutMixin { _controller = CodeController( language: suffix2HighlightMap[_langCode], ); + _textStyle = TextStyle(fontSize: _setting.editorFontSize.fetch()); WidgetsBinding.instance.addPostFrameCallback((Duration duration) async { if (isDarkMode(context)) { @@ -119,6 +121,7 @@ class _EditorPageState extends State with AfterLayoutMixin { child: CodeField( focusNode: _focusNode, controller: _controller, + textStyle: _textStyle, lineNumberStyle: const LineNumberStyle( width: 47, margin: 7, diff --git a/lib/view/page/ping.dart b/lib/view/page/ping.dart index 78694abf..dca7a08c 100644 --- a/lib/view/page/ping.dart +++ b/lib/view/page/ping.dart @@ -75,6 +75,7 @@ class _PingPageState extends State context: context, title: Text(_s.choose), child: Input( + autoFocus: true, controller: _textEditingController, hint: _s.inputDomainHere, maxLines: 1, diff --git a/lib/view/page/pkg.dart b/lib/view/page/pkg.dart index 02221fff..081fae77 100644 --- a/lib/view/page/pkg.dart +++ b/lib/view/page/pkg.dart @@ -107,6 +107,7 @@ class _PkgManagePageState extends State context: context, title: Text(widget.spi.user), child: Input( + autoFocus: true, controller: _textController, type: TextInputType.visiblePassword, obscureText: true, diff --git a/lib/view/page/private_key/edit.dart b/lib/view/page/private_key/edit.dart index 0a512c05..1262c192 100644 --- a/lib/view/page/private_key/edit.dart +++ b/lib/view/page/private_key/edit.dart @@ -153,6 +153,7 @@ class _PrivateKeyEditPageState extends State padding: const EdgeInsets.all(13), children: [ Input( + autoFocus: true, controller: _nameController, type: TextInputType.text, node: _nameNode, diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index c9e9d16a..e4cc8aaa 100644 --- a/lib/view/page/server/edit.dart +++ b/lib/view/page/server/edit.dart @@ -119,6 +119,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { Widget _buildForm() { final children = [ Input( + autoFocus: true, controller: _nameController, type: TextInputType.text, node: _nameFocus, diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 71ac9b84..658eb4b6 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -96,6 +96,8 @@ class _ServerPageState extends State return _buildBodySmall(provider: pro, filtered: filtered); }, ); + + // Desktop doesn't support pull to refresh if (isDesktop) { return child; } @@ -138,7 +140,7 @@ class _ServerPageState extends State if (index == 0 && buildTags) return _buildTagsSwitcher(provider); // Issue #130 - if (index == count - 1) return const SizedBox(height: 77); + if (index == count - 1) return height77; if (buildTags) index--; return _buildEachServerCard(provider.servers[filtered[index]]); @@ -229,6 +231,7 @@ class _ServerPageState extends State _buildServerCardTitle(ss, cs, spi), ]; } else { + height = 107; children = [ _buildServerCardTitle(ss, cs, spi), height13, diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 68cc241b..c21b2e0e 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -10,6 +10,7 @@ import 'package:toolbox/core/extension/colorx.dart'; import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/navigator.dart'; import 'package:toolbox/core/extension/stringx.dart'; +import 'package:toolbox/core/persistant_store.dart'; import 'package:toolbox/core/route.dart'; import 'package:toolbox/data/model/app/net_view.dart'; import 'package:toolbox/view/page/setting/virt_key.dart'; @@ -62,7 +63,8 @@ class _SettingPageState extends State { final _nightMode = ValueNotifier(0); final _maxRetryCount = ValueNotifier(0); final _updateInterval = ValueNotifier(0); - final _fontSize = ValueNotifier(0.0); + final _termFontSize = ValueNotifier(0.0); + final _editorFontSize = ValueNotifier(0.0); final _localeCode = ValueNotifier(''); final _editorTheme = ValueNotifier(''); final _editorDarkTheme = ValueNotifier(''); @@ -89,7 +91,8 @@ class _SettingPageState extends State { _updateInterval.value = _setting.serverStatusUpdateInterval.fetch()!; _maxRetryCount.value = _setting.maxRetryCount.fetch()!; _selectedColorValue.value = _setting.primaryColor.fetch()!; - _fontSize.value = _setting.termFontSize.fetch()!; + _termFontSize.value = _setting.termFontSize.fetch()!; + _editorFontSize.value = _setting.editorFontSize.fetch()!; _editorTheme.value = _setting.editorTheme.fetch()!; _editorDarkTheme.value = _setting.editorDarkTheme.fetch()!; _keyboardType.value = _setting.keyboardType.fetch()!; @@ -196,6 +199,7 @@ class _SettingPageState extends State { Widget _buildEditor() { return Column( children: [ + _buildEditorFontSize(), _buildEditorTheme(), _buildEditorDarkTheme(), ].map((e) => RoundRectCard(e)).toList(), @@ -285,6 +289,7 @@ class _SettingPageState extends State { context: context, title: Text(_s.primaryColorSeed), child: Input( + autoFocus: true, onSubmitted: _onSaveColor, controller: ctrl, hint: '#8b2252', @@ -545,45 +550,14 @@ class _SettingPageState extends State { Widget _buildTermFontSize() { return ValueBuilder( - listenable: _fontSize, + listenable: _termFontSize, build: () => ListTile( title: Text(_s.fontSize), trailing: Text( - _fontSize.value.toString(), + _termFontSize.value.toString(), style: textSize15, ), - onTap: () { - final ctrller = - TextEditingController(text: _fontSize.value.toString()); - showRoundDialog( - context: context, - title: Text(_s.fontSize), - child: Input( - controller: ctrller, - type: TextInputType.number, - icon: Icons.font_download, - ), - actions: [ - TextButton( - onPressed: () { - context.pop(); - final fontSize = double.tryParse(ctrller.text); - if (fontSize == null) { - showRoundDialog( - context: context, - title: Text(_s.failed), - child: Text('Parsed failed: ${ctrller.text}'), - ); - return; - } - _fontSize.value = fontSize; - _setting.termFontSize.put(_fontSize.value); - }, - child: Text(_s.ok), - ), - ], - ); - }, + onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize), ), ); } @@ -610,6 +584,7 @@ class _SettingPageState extends State { context: context, title: Text(_s.diskIgnorePath), child: Input( + autoFocus: true, controller: ctrller, label: 'JSON', type: TextInputType.visiblePassword, @@ -880,6 +855,7 @@ class _SettingPageState extends State { context: context, title: Text(_s.homeWidgetUrlConfig), child: Input( + autoFocus: true, controller: ctrl, label: 'JSON', type: TextInputType.visiblePassword, @@ -996,4 +972,58 @@ class _SettingPageState extends State { onTap: () => AppRoute.serverDetailOrder().go(context), ); } + + Widget _buildEditorFontSize() { + return ValueBuilder( + listenable: _editorFontSize, + build: () => ListTile( + title: Text(_s.fontSize), + trailing: Text( + _editorFontSize.value.toString(), + style: textSize15, + ), + onTap: () => + _showFontSizeDialog(_editorFontSize, _setting.editorFontSize), + ), + ); + } + + void _showFontSizeDialog( + ValueNotifier notifier, + StoreProperty property, + ) { + final ctrller = TextEditingController(text: notifier.value.toString()); + void onSave() { + context.pop(); + final fontSize = double.tryParse(ctrller.text); + if (fontSize == null) { + showRoundDialog( + context: context, + title: Text(_s.failed), + child: Text('Parsed failed: ${ctrller.text}'), + ); + return; + } + notifier.value = fontSize; + property.put(fontSize); + } + + showRoundDialog( + context: context, + title: Text(_s.fontSize), + child: Input( + controller: ctrller, + autoFocus: true, + type: TextInputType.number, + icon: Icons.font_download, + onSubmitted: (_) => onSave(), + ), + actions: [ + TextButton( + onPressed: onSave, + child: Text(_s.ok), + ), + ], + ); + } } diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index e1029dcf..9097dc27 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -107,6 +107,7 @@ class _SnippetEditPageState extends State padding: const EdgeInsets.all(13), children: [ Input( + autoFocus: true, controller: _nameController, type: TextInputType.text, onSubmitted: (_) => FocusScope.of(context).requestFocus(_scriptNode), diff --git a/lib/view/page/snippet/list.dart b/lib/view/page/snippet/list.dart index 691de285..c8cd1d85 100644 --- a/lib/view/page/snippet/list.dart +++ b/lib/view/page/snippet/list.dart @@ -68,7 +68,7 @@ class _SnippetListPageState extends State { .toList(); return ReorderableListView.builder( - padding: const EdgeInsets.all(13), + padding: const EdgeInsets.symmetric(horizontal: 13), itemCount: filtered.length, onReorder: (oldIdx, newIdx) => setState(() { provider.snippets.moveByItem( @@ -87,6 +87,7 @@ class _SnippetListPageState extends State { all: _s.all, width: _media.size.width, ), + footer: height77, buildDefaultDragHandles: false, itemBuilder: (context, idx) { final snippet = filtered.elementAt(idx); diff --git a/lib/view/page/storage/local.dart b/lib/view/page/storage/local.dart index c3ce34e0..88395c0c 100644 --- a/lib/view/page/storage/local.dart +++ b/lib/view/page/storage/local.dart @@ -345,6 +345,7 @@ class _LocalStoragePageState extends State { context: context, title: Text(_s.rename), child: Input( + autoFocus: true, controller: TextEditingController(text: fileName), onSubmitted: (p0) { context.pop(); diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index 9d2c177a..0f3f0d11 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -246,6 +246,8 @@ class _SftpPageState extends State { mainAxisSize: MainAxisSize.min, children: [ Input( + autoFocus: true, + icon: Icons.abc, label: _s.path, onSubmitted: (value) => context.pop(value), ), @@ -492,6 +494,8 @@ class _SftpPageState extends State { context: context, title: Text(_s.createFolder), child: Input( + autoFocus: true, + icon: Icons.folder, controller: textController, label: _s.name, ), @@ -533,6 +537,8 @@ class _SftpPageState extends State { context: context, title: Text(_s.createFile), child: Input( + autoFocus: true, + icon: Icons.insert_drive_file, controller: textController, label: _s.name, ), @@ -576,6 +582,8 @@ class _SftpPageState extends State { context: context, title: Text(_s.rename), child: Input( + autoFocus: true, + icon: Icons.abc, controller: textController, label: _s.name, ), diff --git a/lib/view/widget/input_field.dart b/lib/view/widget/input_field.dart index 29fb9357..964d93e0 100644 --- a/lib/view/widget/input_field.dart +++ b/lib/view/widget/input_field.dart @@ -18,6 +18,7 @@ class Input extends StatelessWidget { final bool suggestiion; final String? errorText; final Widget? prefix; + final bool autoFocus; const Input({ super.key, @@ -36,6 +37,7 @@ class Input extends StatelessWidget { this.suggestiion = false, this.errorText, this.prefix, + this.autoFocus = false, }); @override Widget build(BuildContext context) { @@ -49,6 +51,7 @@ class Input extends StatelessWidget { onChanged: onChanged, keyboardType: type, focusNode: node, + autofocus: autoFocus, autocorrect: autoCorrect, enableSuggestions: suggestiion, decoration: InputDecoration( @@ -57,7 +60,7 @@ class Input extends StatelessWidget { icon: icon != null ? Icon(icon) : null, border: InputBorder.none, errorText: errorText, - prefix: prefix), + prefix: prefix,), controller: controller, obscureText: obscureText, ), diff --git a/lib/view/widget/tag.dart b/lib/view/widget/tag.dart index 2ffa88b3..1e19a00e 100644 --- a/lib/view/widget/tag.dart +++ b/lib/view/widget/tag.dart @@ -60,7 +60,7 @@ class TagEditor extends StatelessWidget { trailing: InkWell( child: const Icon(Icons.add), onTap: () { - _showTagDialog(context, tags, onChanged); + _showAddTagDialog(context, tags, onChanged); }, ), )); @@ -72,7 +72,7 @@ class TagEditor extends StatelessWidget { final counts = tags.length + suggestionLen + (suggestionLen == 0 ? 0 : 1); if (counts == 0) return Text(s.tag); return ConstrainedBox( - constraints: const BoxConstraints(maxHeight: 27), + constraints: const BoxConstraints(maxHeight: _kTagBtnHeight), child: ListView.builder( scrollDirection: Axis.horizontal, itemBuilder: (context, index) { @@ -101,7 +101,7 @@ class TagEditor extends StatelessWidget { Text( '#$tag', textAlign: TextAlign.center, - style: textSize13, + style: isAdd ? textSize13Grey : textSize13, textScaleFactor: 1.0, ), const SizedBox(width: 4.0), @@ -123,7 +123,7 @@ class TagEditor extends StatelessWidget { ); } - void _showTagDialog( + void _showAddTagDialog( BuildContext context, List tags, void Function(List)? onChanged, @@ -133,6 +133,8 @@ class TagEditor extends StatelessWidget { context: context, title: Text(s.add), child: Input( + autoFocus: true, + icon: Icons.tag, controller: textEditingController, hint: s.tag, ), @@ -156,6 +158,8 @@ class TagEditor extends StatelessWidget { context: context, title: Text(s.rename), child: Input( + autoFocus: true, + icon: Icons.abc, controller: textEditingController, hint: s.tag, ),