new & opt.

opt.: input field auto focus
opt.: snippet page top padding
new: setting of editor font size
This commit is contained in:
lollipopkit
2023-08-21 13:54:09 +08:00
parent 6a2191ff92
commit e3f2b211a9
16 changed files with 106 additions and 43 deletions

View File

@@ -27,6 +27,7 @@ const roundRectCardPadding = EdgeInsets.symmetric(horizontal: 17, vertical: 13);
const placeholder = SizedBox(); const placeholder = SizedBox();
const height13 = SizedBox(height: 13); const height13 = SizedBox(height: 13);
const height77 = SizedBox(height: 77);
const width13 = SizedBox(width: 13); const width13 = SizedBox(width: 13);
const width7 = SizedBox(width: 7); const width7 = SizedBox(width: 7);

View File

@@ -71,6 +71,9 @@ class SettingStore extends PersistentStore {
StoreProperty<bool> get sshVirtualKeyAutoOff => StoreProperty<bool> get sshVirtualKeyAutoOff =>
property('sshVirtualKeyAutoOff', defaultValue: true); property('sshVirtualKeyAutoOff', defaultValue: true);
StoreProperty<double> get editorFontSize =>
property('editorFontSize', defaultValue: 13);
// Editor theme // Editor theme
StoreProperty<String> get editorTheme => StoreProperty<String> get editorTheme =>
property('editorTheme', defaultValue: defaultEditorTheme); property('editorTheme', defaultValue: defaultEditorTheme);

View File

@@ -103,6 +103,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Input( Input(
autoFocus: true,
type: TextInputType.text, type: TextInputType.text,
label: _s.image, label: _s.image,
hint: 'xxx:1.1', hint: 'xxx:1.1',

View File

@@ -33,6 +33,7 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
Map<String, TextStyle>? _codeTheme; Map<String, TextStyle>? _codeTheme;
late S _s; late S _s;
late String? _langCode; late String? _langCode;
late TextStyle _textStyle;
@override @override
void initState() { void initState() {
@@ -41,6 +42,7 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
_controller = CodeController( _controller = CodeController(
language: suffix2HighlightMap[_langCode], language: suffix2HighlightMap[_langCode],
); );
_textStyle = TextStyle(fontSize: _setting.editorFontSize.fetch());
WidgetsBinding.instance.addPostFrameCallback((Duration duration) async { WidgetsBinding.instance.addPostFrameCallback((Duration duration) async {
if (isDarkMode(context)) { if (isDarkMode(context)) {
@@ -119,6 +121,7 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
child: CodeField( child: CodeField(
focusNode: _focusNode, focusNode: _focusNode,
controller: _controller, controller: _controller,
textStyle: _textStyle,
lineNumberStyle: const LineNumberStyle( lineNumberStyle: const LineNumberStyle(
width: 47, width: 47,
margin: 7, margin: 7,

View File

@@ -75,6 +75,7 @@ class _PingPageState extends State<PingPage>
context: context, context: context,
title: Text(_s.choose), title: Text(_s.choose),
child: Input( child: Input(
autoFocus: true,
controller: _textEditingController, controller: _textEditingController,
hint: _s.inputDomainHere, hint: _s.inputDomainHere,
maxLines: 1, maxLines: 1,

View File

@@ -107,6 +107,7 @@ class _PkgManagePageState extends State<PkgPage>
context: context, context: context,
title: Text(widget.spi.user), title: Text(widget.spi.user),
child: Input( child: Input(
autoFocus: true,
controller: _textController, controller: _textController,
type: TextInputType.visiblePassword, type: TextInputType.visiblePassword,
obscureText: true, obscureText: true,

View File

@@ -153,6 +153,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
padding: const EdgeInsets.all(13), padding: const EdgeInsets.all(13),
children: [ children: [
Input( Input(
autoFocus: true,
controller: _nameController, controller: _nameController,
type: TextInputType.text, type: TextInputType.text,
node: _nameNode, node: _nameNode,

View File

@@ -119,6 +119,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
Widget _buildForm() { Widget _buildForm() {
final children = [ final children = [
Input( Input(
autoFocus: true,
controller: _nameController, controller: _nameController,
type: TextInputType.text, type: TextInputType.text,
node: _nameFocus, node: _nameFocus,

View File

@@ -96,6 +96,8 @@ class _ServerPageState extends State<ServerPage>
return _buildBodySmall(provider: pro, filtered: filtered); return _buildBodySmall(provider: pro, filtered: filtered);
}, },
); );
// Desktop doesn't support pull to refresh
if (isDesktop) { if (isDesktop) {
return child; return child;
} }
@@ -138,7 +140,7 @@ class _ServerPageState extends State<ServerPage>
if (index == 0 && buildTags) return _buildTagsSwitcher(provider); if (index == 0 && buildTags) return _buildTagsSwitcher(provider);
// Issue #130 // Issue #130
if (index == count - 1) return const SizedBox(height: 77); if (index == count - 1) return height77;
if (buildTags) index--; if (buildTags) index--;
return _buildEachServerCard(provider.servers[filtered[index]]); return _buildEachServerCard(provider.servers[filtered[index]]);
@@ -229,6 +231,7 @@ class _ServerPageState extends State<ServerPage>
_buildServerCardTitle(ss, cs, spi), _buildServerCardTitle(ss, cs, spi),
]; ];
} else { } else {
height = 107;
children = [ children = [
_buildServerCardTitle(ss, cs, spi), _buildServerCardTitle(ss, cs, spi),
height13, height13,

View File

@@ -10,6 +10,7 @@ import 'package:toolbox/core/extension/colorx.dart';
import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/locale.dart';
import 'package:toolbox/core/extension/navigator.dart'; import 'package:toolbox/core/extension/navigator.dart';
import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/persistant_store.dart';
import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/route.dart';
import 'package:toolbox/data/model/app/net_view.dart'; import 'package:toolbox/data/model/app/net_view.dart';
import 'package:toolbox/view/page/setting/virt_key.dart'; import 'package:toolbox/view/page/setting/virt_key.dart';
@@ -62,7 +63,8 @@ class _SettingPageState extends State<SettingPage> {
final _nightMode = ValueNotifier(0); final _nightMode = ValueNotifier(0);
final _maxRetryCount = ValueNotifier(0); final _maxRetryCount = ValueNotifier(0);
final _updateInterval = 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 _localeCode = ValueNotifier('');
final _editorTheme = ValueNotifier(''); final _editorTheme = ValueNotifier('');
final _editorDarkTheme = ValueNotifier(''); final _editorDarkTheme = ValueNotifier('');
@@ -89,7 +91,8 @@ class _SettingPageState extends State<SettingPage> {
_updateInterval.value = _setting.serverStatusUpdateInterval.fetch()!; _updateInterval.value = _setting.serverStatusUpdateInterval.fetch()!;
_maxRetryCount.value = _setting.maxRetryCount.fetch()!; _maxRetryCount.value = _setting.maxRetryCount.fetch()!;
_selectedColorValue.value = _setting.primaryColor.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()!; _editorTheme.value = _setting.editorTheme.fetch()!;
_editorDarkTheme.value = _setting.editorDarkTheme.fetch()!; _editorDarkTheme.value = _setting.editorDarkTheme.fetch()!;
_keyboardType.value = _setting.keyboardType.fetch()!; _keyboardType.value = _setting.keyboardType.fetch()!;
@@ -196,6 +199,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildEditor() { Widget _buildEditor() {
return Column( return Column(
children: [ children: [
_buildEditorFontSize(),
_buildEditorTheme(), _buildEditorTheme(),
_buildEditorDarkTheme(), _buildEditorDarkTheme(),
].map((e) => RoundRectCard(e)).toList(), ].map((e) => RoundRectCard(e)).toList(),
@@ -285,6 +289,7 @@ class _SettingPageState extends State<SettingPage> {
context: context, context: context,
title: Text(_s.primaryColorSeed), title: Text(_s.primaryColorSeed),
child: Input( child: Input(
autoFocus: true,
onSubmitted: _onSaveColor, onSubmitted: _onSaveColor,
controller: ctrl, controller: ctrl,
hint: '#8b2252', hint: '#8b2252',
@@ -545,45 +550,14 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildTermFontSize() { Widget _buildTermFontSize() {
return ValueBuilder( return ValueBuilder(
listenable: _fontSize, listenable: _termFontSize,
build: () => ListTile( build: () => ListTile(
title: Text(_s.fontSize), title: Text(_s.fontSize),
trailing: Text( trailing: Text(
_fontSize.value.toString(), _termFontSize.value.toString(),
style: textSize15, style: textSize15,
), ),
onTap: () { onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize),
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),
),
],
);
},
), ),
); );
} }
@@ -610,6 +584,7 @@ class _SettingPageState extends State<SettingPage> {
context: context, context: context,
title: Text(_s.diskIgnorePath), title: Text(_s.diskIgnorePath),
child: Input( child: Input(
autoFocus: true,
controller: ctrller, controller: ctrller,
label: 'JSON', label: 'JSON',
type: TextInputType.visiblePassword, type: TextInputType.visiblePassword,
@@ -880,6 +855,7 @@ class _SettingPageState extends State<SettingPage> {
context: context, context: context,
title: Text(_s.homeWidgetUrlConfig), title: Text(_s.homeWidgetUrlConfig),
child: Input( child: Input(
autoFocus: true,
controller: ctrl, controller: ctrl,
label: 'JSON', label: 'JSON',
type: TextInputType.visiblePassword, type: TextInputType.visiblePassword,
@@ -996,4 +972,58 @@ class _SettingPageState extends State<SettingPage> {
onTap: () => AppRoute.serverDetailOrder().go(context), 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<double> 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),
),
],
);
}
} }

View File

@@ -107,6 +107,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
padding: const EdgeInsets.all(13), padding: const EdgeInsets.all(13),
children: [ children: [
Input( Input(
autoFocus: true,
controller: _nameController, controller: _nameController,
type: TextInputType.text, type: TextInputType.text,
onSubmitted: (_) => FocusScope.of(context).requestFocus(_scriptNode), onSubmitted: (_) => FocusScope.of(context).requestFocus(_scriptNode),

View File

@@ -68,7 +68,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
.toList(); .toList();
return ReorderableListView.builder( return ReorderableListView.builder(
padding: const EdgeInsets.all(13), padding: const EdgeInsets.symmetric(horizontal: 13),
itemCount: filtered.length, itemCount: filtered.length,
onReorder: (oldIdx, newIdx) => setState(() { onReorder: (oldIdx, newIdx) => setState(() {
provider.snippets.moveByItem( provider.snippets.moveByItem(
@@ -87,6 +87,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
all: _s.all, all: _s.all,
width: _media.size.width, width: _media.size.width,
), ),
footer: height77,
buildDefaultDragHandles: false, buildDefaultDragHandles: false,
itemBuilder: (context, idx) { itemBuilder: (context, idx) {
final snippet = filtered.elementAt(idx); final snippet = filtered.elementAt(idx);

View File

@@ -345,6 +345,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
context: context, context: context,
title: Text(_s.rename), title: Text(_s.rename),
child: Input( child: Input(
autoFocus: true,
controller: TextEditingController(text: fileName), controller: TextEditingController(text: fileName),
onSubmitted: (p0) { onSubmitted: (p0) {
context.pop(); context.pop();

View File

@@ -246,6 +246,8 @@ class _SftpPageState extends State<SftpPage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Input( Input(
autoFocus: true,
icon: Icons.abc,
label: _s.path, label: _s.path,
onSubmitted: (value) => context.pop(value), onSubmitted: (value) => context.pop(value),
), ),
@@ -492,6 +494,8 @@ class _SftpPageState extends State<SftpPage> {
context: context, context: context,
title: Text(_s.createFolder), title: Text(_s.createFolder),
child: Input( child: Input(
autoFocus: true,
icon: Icons.folder,
controller: textController, controller: textController,
label: _s.name, label: _s.name,
), ),
@@ -533,6 +537,8 @@ class _SftpPageState extends State<SftpPage> {
context: context, context: context,
title: Text(_s.createFile), title: Text(_s.createFile),
child: Input( child: Input(
autoFocus: true,
icon: Icons.insert_drive_file,
controller: textController, controller: textController,
label: _s.name, label: _s.name,
), ),
@@ -576,6 +582,8 @@ class _SftpPageState extends State<SftpPage> {
context: context, context: context,
title: Text(_s.rename), title: Text(_s.rename),
child: Input( child: Input(
autoFocus: true,
icon: Icons.abc,
controller: textController, controller: textController,
label: _s.name, label: _s.name,
), ),

View File

@@ -18,6 +18,7 @@ class Input extends StatelessWidget {
final bool suggestiion; final bool suggestiion;
final String? errorText; final String? errorText;
final Widget? prefix; final Widget? prefix;
final bool autoFocus;
const Input({ const Input({
super.key, super.key,
@@ -36,6 +37,7 @@ class Input extends StatelessWidget {
this.suggestiion = false, this.suggestiion = false,
this.errorText, this.errorText,
this.prefix, this.prefix,
this.autoFocus = false,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -49,6 +51,7 @@ class Input extends StatelessWidget {
onChanged: onChanged, onChanged: onChanged,
keyboardType: type, keyboardType: type,
focusNode: node, focusNode: node,
autofocus: autoFocus,
autocorrect: autoCorrect, autocorrect: autoCorrect,
enableSuggestions: suggestiion, enableSuggestions: suggestiion,
decoration: InputDecoration( decoration: InputDecoration(
@@ -57,7 +60,7 @@ class Input extends StatelessWidget {
icon: icon != null ? Icon(icon) : null, icon: icon != null ? Icon(icon) : null,
border: InputBorder.none, border: InputBorder.none,
errorText: errorText, errorText: errorText,
prefix: prefix), prefix: prefix,),
controller: controller, controller: controller,
obscureText: obscureText, obscureText: obscureText,
), ),

View File

@@ -60,7 +60,7 @@ class TagEditor extends StatelessWidget {
trailing: InkWell( trailing: InkWell(
child: const Icon(Icons.add), child: const Icon(Icons.add),
onTap: () { 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); final counts = tags.length + suggestionLen + (suggestionLen == 0 ? 0 : 1);
if (counts == 0) return Text(s.tag); if (counts == 0) return Text(s.tag);
return ConstrainedBox( return ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 27), constraints: const BoxConstraints(maxHeight: _kTagBtnHeight),
child: ListView.builder( child: ListView.builder(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemBuilder: (context, index) { itemBuilder: (context, index) {
@@ -101,7 +101,7 @@ class TagEditor extends StatelessWidget {
Text( Text(
'#$tag', '#$tag',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: textSize13, style: isAdd ? textSize13Grey : textSize13,
textScaleFactor: 1.0, textScaleFactor: 1.0,
), ),
const SizedBox(width: 4.0), const SizedBox(width: 4.0),
@@ -123,7 +123,7 @@ class TagEditor extends StatelessWidget {
); );
} }
void _showTagDialog( void _showAddTagDialog(
BuildContext context, BuildContext context,
List<String> tags, List<String> tags,
void Function(List<String>)? onChanged, void Function(List<String>)? onChanged,
@@ -133,6 +133,8 @@ class TagEditor extends StatelessWidget {
context: context, context: context,
title: Text(s.add), title: Text(s.add),
child: Input( child: Input(
autoFocus: true,
icon: Icons.tag,
controller: textEditingController, controller: textEditingController,
hint: s.tag, hint: s.tag,
), ),
@@ -156,6 +158,8 @@ class TagEditor extends StatelessWidget {
context: context, context: context,
title: Text(s.rename), title: Text(s.rename),
child: Input( child: Input(
autoFocus: true,
icon: Icons.abc,
controller: textEditingController, controller: textEditingController,
hint: s.tag, hint: s.tag,
), ),