优化使用体验

This commit is contained in:
jyuesong
2022-01-19 15:14:29 +08:00
parent 16f4f27f17
commit 3959155c1b
8 changed files with 190 additions and 133 deletions

View File

@@ -20,16 +20,23 @@ class QlAppBar extends StatelessWidget with PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget back = backWidget ?? Widget back = backWidget ??
GestureDetector( InkWell(
onTap: () { onTap: () {
if (backCall != null) { if (backCall != null) {
backCall!(); backCall!();
} else {
Navigator.of(context).pop();
} }
}, },
child: const Center( child: const Padding(
child: Icon( padding: EdgeInsets.symmetric(
CupertinoIcons.left_chevron, horizontal: 15,
color: Colors.white, ),
child: Center(
child: Icon(
CupertinoIcons.left_chevron,
color: Colors.white,
),
), ),
), ),
); );

View File

@@ -63,6 +63,16 @@ ThemeData darkTheme = ThemeData.dark().copyWith(
color: _primaryColor, color: _primaryColor,
), ),
), ),
border: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xff999999),
),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xff999999),
),
),
), ),
tabBarTheme: const TabBarTheme( tabBarTheme: const TabBarTheme(
labelStyle: TextStyle( labelStyle: TextStyle(
@@ -108,6 +118,16 @@ ThemeData lightTheme = ThemeData.light().copyWith(
color: _primaryColor, color: _primaryColor,
), ),
), ),
border: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xff999999),
),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xff999999),
),
),
), ),
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
backgroundColor: _primaryColor, backgroundColor: _primaryColor,

View File

@@ -21,11 +21,17 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
String? value; String? value;
late TextEditingController _controller; late TextEditingController _controller;
FocusNode node = FocusNode();
@override @override
void initState() { void initState() {
_controller = TextEditingController(text: widget.content); _controller = TextEditingController(text: widget.content);
super.initState(); super.initState();
WidgetsBinding.instance?.addPostFrameCallback(
(timeStamp) {
node.requestFocus();
},
);
} }
@override @override
@@ -44,8 +50,7 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
"请先点击保存".toast(); "请先点击保存".toast();
return; return;
} }
HttpResponse<NullResponse> response = HttpResponse<NullResponse> response = await Api.saveFile(widget.title, _controller.text);
await Api.saveFile(widget.title, _controller.text);
if (response.success) { if (response.success) {
ref.read(configProvider).loadContent(widget.title); ref.read(configProvider).loadContent(widget.title);
Navigator.of(context).pop(); Navigator.of(context).pop();
@@ -58,7 +63,13 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
horizontal: 15, horizontal: 15,
), ),
child: Center( child: Center(
child: Text("提交"), child: Text(
"提交",
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
), ),
), ),
) )
@@ -71,7 +82,7 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
), ),
child: SingleChildScrollView( child: SingleChildScrollView(
child: TextField( child: TextField(
focusNode: FocusNode(), focusNode: node,
style: TextStyle( style: TextStyle(
color: ref.read(themeProvider).themeColor.descColor(), color: ref.read(themeProvider).themeColor.descColor(),
fontSize: 14, fontSize: 14,

View File

@@ -22,6 +22,7 @@ class _AddEnvPageState extends ConsumerState<AddEnvPage> {
final TextEditingController _nameController = TextEditingController(); final TextEditingController _nameController = TextEditingController();
final TextEditingController _valueController = TextEditingController(); final TextEditingController _valueController = TextEditingController();
final TextEditingController _remarkController = TextEditingController(); final TextEditingController _remarkController = TextEditingController();
FocusNode focusNode = FocusNode();
@override @override
void initState() { void initState() {
@@ -34,6 +35,11 @@ class _AddEnvPageState extends ConsumerState<AddEnvPage> {
} else { } else {
envBean = EnvBean(); envBean = EnvBean();
} }
WidgetsBinding.instance?.addPostFrameCallback(
(timeStamp) {
focusNode.requestFocus();
},
);
} }
@override @override
@@ -95,6 +101,7 @@ class _AddEnvPageState extends ConsumerState<AddEnvPage> {
height: 10, height: 10,
), ),
TextField( TextField(
focusNode: focusNode,
controller: _nameController, controller: _nameController,
decoration: const InputDecoration( decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
@@ -190,9 +197,7 @@ class _AddEnvPageState extends ConsumerState<AddEnvPage> {
envBean.name = _nameController.text; envBean.name = _nameController.text;
envBean.value = _valueController.text; envBean.value = _valueController.text;
envBean.remarks = _remarkController.text; envBean.remarks = _remarkController.text;
HttpResponse<NullResponse> response = await Api.addEnv( HttpResponse<NullResponse> response = await Api.addEnv(_nameController.text, _valueController.text, _remarkController.text, id: envBean.sId);
_nameController.text, _valueController.text, _remarkController.text,
id: envBean.sId);
if (response.success) { if (response.success) {
"操作成功".toast(); "操作成功".toast();

View File

@@ -35,45 +35,49 @@ class _HomePageState extends ConsumerState<HomePage> {
List<Widget> actions = []; List<Widget> actions = [];
if (_index == 0) { if (_index == 0) {
actions.add(InkWell( actions.add(
onTap: () { InkWell(
Navigator.of(context).pushNamed( onTap: () {
Routes.routeAddTask, Navigator.of(context).pushNamed(
); Routes.routeAddTask,
}, );
child: const Padding( },
padding: EdgeInsets.symmetric( child: const Padding(
horizontal: 15, padding: EdgeInsets.symmetric(
), horizontal: 15,
child: Center( ),
child: Icon( child: Center(
CupertinoIcons.add, child: Icon(
size: 20, CupertinoIcons.add,
color: Colors.white, size: 24,
color: Colors.white,
),
), ),
), ),
), ),
)); );
} else if (_index == 1) { } else if (_index == 1) {
actions.add(InkWell( actions.add(
onTap: () { InkWell(
Navigator.of(context).pushNamed( onTap: () {
Routes.routeAddEnv, Navigator.of(context).pushNamed(
); Routes.routeAddEnv,
}, );
child: const Padding( },
padding: EdgeInsets.symmetric( child: const Padding(
horizontal: 15, padding: EdgeInsets.symmetric(
), horizontal: 15,
child: Center( ),
child: Icon( child: Center(
CupertinoIcons.add, child: Icon(
size: 20, CupertinoIcons.add,
color: Colors.white, size: 24,
color: Colors.white,
),
), ),
), ),
), ),
)); );
} else if (_index == 2) { } else if (_index == 2) {
actions.add(InkWell( actions.add(InkWell(
onTap: () { onTap: () {

View File

@@ -56,90 +56,88 @@ class _AddDependencyPageState extends ConsumerState<AddDependenyPage> {
) )
], ],
), ),
body: Container( body: Column(
child: Column( mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, children: [
children: [ Padding(
Padding( padding: const EdgeInsets.symmetric(
padding: const EdgeInsets.symmetric( horizontal: 15,
horizontal: 15,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 10,
),
const Text(
"依赖类型:",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 10,
),
DropdownButtonFormField<DepedencyEnum>(
items: [
DropdownMenuItem(
value: DepedencyEnum.NodeJS,
child: Text(DepedencyEnum.NodeJS.name),
),
DropdownMenuItem(
value: DepedencyEnum.Python3,
child: Text(DepedencyEnum.Python3.name),
),
DropdownMenuItem(
value: DepedencyEnum.Linux,
child: Text(DepedencyEnum.Linux.name),
),
],
value: DepedencyEnum.NodeJS,
onChanged: (value) {
depedencyType = value!;
},
),
],
),
), ),
Padding( child: Column(
padding: const EdgeInsets.symmetric( mainAxisSize: MainAxisSize.min,
horizontal: 15, crossAxisAlignment: CrossAxisAlignment.start,
), children: [
child: Column( const SizedBox(
mainAxisSize: MainAxisSize.min, height: 10,
crossAxisAlignment: CrossAxisAlignment.start, ),
children: [ const Text(
const SizedBox( "依赖类型:",
height: 10, style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
const Text( ),
"名称:", const SizedBox(
style: TextStyle( height: 10,
fontSize: 16, ),
fontWeight: FontWeight.w600, DropdownButtonFormField<DepedencyEnum>(
items: [
DropdownMenuItem(
value: DepedencyEnum.NodeJS,
child: Text(DepedencyEnum.NodeJS.name),
), ),
), DropdownMenuItem(
const SizedBox( value: DepedencyEnum.Python3,
height: 10, child: Text(DepedencyEnum.Python3.name),
),
TextField(
controller: _nameController,
decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
hintText: "请输入名称",
), ),
autofocus: false, DropdownMenuItem(
), value: DepedencyEnum.Linux,
], child: Text(DepedencyEnum.Linux.name),
), ),
],
value: DepedencyEnum.NodeJS,
onChanged: (value) {
depedencyType = value!;
},
),
],
), ),
], ),
), Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 10,
),
const Text(
"名称:",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 10,
),
TextField(
controller: _nameController,
decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
hintText: "请输入名称",
),
autofocus: false,
),
],
),
),
],
), ),
); );
} }

View File

@@ -63,7 +63,7 @@ class _DependcyPageState extends State<DependencyPage> with TickerProviderStateM
child: Center( child: Center(
child: Icon( child: Icon(
CupertinoIcons.add, CupertinoIcons.add,
size: 20, size: 24,
color: Colors.white, color: Colors.white,
), ),
), ),

View File

@@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:qinglong_app/base/http/api.dart'; import 'package:qinglong_app/base/http/api.dart';
import 'package:qinglong_app/base/http/http.dart'; import 'package:qinglong_app/base/http/http.dart';
@@ -24,8 +23,7 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
final TextEditingController _commandController = TextEditingController(); final TextEditingController _commandController = TextEditingController();
final TextEditingController _cronController = TextEditingController(); final TextEditingController _cronController = TextEditingController();
FocusNode focusNode = FocusNode();
final String scheduleCron = r"[ \t]*(@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly|((((([1-5]?[0-9])-)?([1-5]?[0-9])|\*)(/([1-5]?[0-9]))?,)*((([1-5]?[0-9])-)?([1-5]?[0-9])|\*)(/([1-5]?[0-9]))?)[ \t]+(((((2[0-3]|1[0-9]|[0-9])-)?(2[0-3]|1[0-9]|[0-9])|\*)(/(2[0-3]|1[0-9]|[0-9]))?,)*(((2[0-3]|1[0-9]|[0-9])-)?(2[0-3]|1[0-9]|[0-9])|\*)(/(2[0-3]|1[0-9]|[0-9]))?)[ \t]+(((((3[01]|[12][0-9]|[1-9])-)?(3[01]|[12][0-9]|[1-9])|\*)(/(3[01]|[12][0-9]|[1-9]))?,)*(((3[01]|[12][0-9]|[1-9])-)?(3[01]|[12][0-9]|[1-9])|\*)(/(3[01]|[12][0-9]|[1-9]))?)[ \t]+((((((1[0-2]|[1-9])|[Jj][Aa][Nn]|[Ff][Ee][Bb]|[Mm][Aa][Rr]|[Aa][Pp][Rr]|[Mm][Aa][Yy]|[Jj][Uu][Nn]|[Jj][Uu][Ll]|[Aa][Uu][Gg]|[Ss][Ee][Pp]|[Oo][Cc][Tt]|[Nn][Oo][Vv]|[Dd][Ee][Cc])-)?((1[0-2]|[1-9])|[Jj][Aa][Nn]|[Ff][Ee][Bb]|[Mm][Aa][Rr]|[Aa][Pp][Rr]|[Mm][Aa][Yy]|[Jj][Uu][Nn]|[Jj][Uu][Ll]|[Aa][Uu][Gg]|[Ss][Ee][Pp]|[Oo][Cc][Tt]|[Nn][Oo][Vv]|[Dd][Ee][Cc])|\*)(/((1[0-2]|[1-9])|[Jj][Aa][Nn]|[Ff][Ee][Bb]|[Mm][Aa][Rr]|[Aa][Pp][Rr]|[Mm][Aa][Yy]|[Jj][Uu][Nn]|[Jj][Uu][Ll]|[Aa][Uu][Gg]|[Ss][Ee][Pp]|[Oo][Cc][Tt]|[Nn][Oo][Vv]|[Dd][Ee][Cc]))?,)*((((1[0-2]|[1-9])|[Jj][Aa][Nn]|[Ff][Ee][Bb]|[Mm][Aa][Rr]|[Aa][Pp][Rr]|[Mm][Aa][Yy]|[Jj][Uu][Nn]|[Jj][Uu][Ll]|[Aa][Uu][Gg]|[Ss][Ee][Pp]|[Oo][Cc][Tt]|[Nn][Oo][Vv]|[Dd][Ee][Cc])-)?((1[0-2]|[1-9])|[Jj][Aa][Nn]|[Ff][Ee][Bb]|[Mm][Aa][Rr]|[Aa][Pp][Rr]|[Mm][Aa][Yy]|[Jj][Uu][Nn]|[Jj][Uu][Ll]|[Aa][Uu][Gg]|[Ss][Ee][Pp]|[Oo][Cc][Tt]|[Nn][Oo][Vv]|[Dd][Ee][Cc])|\*)(/((1[0-2]|[1-9])|[Jj][Aa][Nn]|[Ff][Ee][Bb]|[Mm][Aa][Rr]|[Aa][Pp][Rr]|[Mm][Aa][Yy]|[Jj][Uu][Nn]|[Jj][Uu][Ll]|[Aa][Uu][Gg]|[Ss][Ee][Pp]|[Oo][Cc][Tt]|[Nn][Oo][Vv]|[Dd][Ee][Cc]))?)[ \t]+((((([0-7]|[Ss][Uu][Nn]|[Mm][Oo][Nn]|[Tt][Uu][Ee]|[Ww][Ee][Dd]|[Tt][Hh][Uu]|[Ff][Rr][Ii]|[Ss][Aa][Tt])-)?([0-7]|[Ss][Uu][Nn]|[Mm][Oo][Nn]|[Tt][Uu][Ee]|[Ww][Ee][Dd]|[Tt][Hh][Uu]|[Ff][Rr][Ii]|[Ss][Aa][Tt])|\*)(/([0-7]|[Ss][Uu][Nn]|[Mm][Oo][Nn]|[Tt][Uu][Ee]|[Ww][Ee][Dd]|[Tt][Hh][Uu]|[Ff][Rr][Ii]|[Ss][Aa][Tt]))?,)*((([0-7]|[Ss][Uu][Nn]|[Mm][Oo][Nn]|[Tt][Uu][Ee]|[Ww][Ee][Dd]|[Tt][Hh][Uu]|[Ff][Rr][Ii]|[Ss][Aa][Tt])-)?([0-7]|[Ss][Uu][Nn]|[Mm][Oo][Nn]|[Tt][Uu][Ee]|[Ww][Ee][Dd]|[Tt][Hh][Uu]|[Ff][Rr][Ii]|[Ss][Aa][Tt])|\*)(/([0-7]|[Ss][Uu][Nn]|[Mm][Oo][Nn]|[Tt][Uu][Ee]|[Ww][Ee][Dd]|[Tt][Hh][Uu]|[Ff][Rr][Ii]|[Ss][Aa][Tt]))?))[ \t]*$";
@override @override
void initState() { void initState() {
@@ -38,6 +36,11 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
} else { } else {
taskBean = TaskBean(); taskBean = TaskBean();
} }
WidgetsBinding.instance?.addPostFrameCallback(
(timeStamp) {
focusNode.requestFocus();
},
);
} }
@override @override
@@ -98,6 +101,7 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
height: 10, height: 10,
), ),
TextField( TextField(
focusNode: focusNode,
controller: _nameController, controller: _nameController,
decoration: const InputDecoration( decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
@@ -133,9 +137,6 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
controller: _commandController, controller: _commandController,
maxLines: 4, maxLines: 4,
minLines: 1, minLines: 1,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(scheduleCron)),
],
decoration: const InputDecoration( decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
hintText: "请输入命令", hintText: "请输入命令",
@@ -174,6 +175,15 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
), ),
autofocus: false, autofocus: false,
), ),
const SizedBox(
height: 5,
),
const Text(
"定时的cron不校验,自己确保写的是正确的cron",
style: TextStyle(
fontSize: 12,
),
),
], ],
), ),
), ),
@@ -196,12 +206,14 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
return; return;
} }
commitReal();
}
void commitReal() async {
taskBean.name = _nameController.text; taskBean.name = _nameController.text;
taskBean.command = _commandController.text; taskBean.command = _commandController.text;
taskBean.schedule = _cronController.text; taskBean.schedule = _cronController.text;
HttpResponse<NullResponse> response = await Api.addTask( HttpResponse<NullResponse> response = await Api.addTask(_nameController.text, _commandController.text, _cronController.text, id: taskBean.sId);
_nameController.text, _commandController.text, _cronController.text,
id: taskBean.sId);
if (response.success) { if (response.success) {
"操作成功".toast(); "操作成功".toast();