优化使用体验

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
Widget build(BuildContext context) {
Widget back = backWidget ??
GestureDetector(
InkWell(
onTap: () {
if (backCall != null) {
backCall!();
} else {
Navigator.of(context).pop();
}
},
child: const Center(
child: Icon(
CupertinoIcons.left_chevron,
color: Colors.white,
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 15,
),
child: Center(
child: Icon(
CupertinoIcons.left_chevron,
color: Colors.white,
),
),
),
);

View File

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

View File

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

View File

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

View File

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

View File

@@ -56,90 +56,88 @@ class _AddDependencyPageState extends ConsumerState<AddDependenyPage> {
)
],
),
body: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
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,
),
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!;
},
),
],
),
body: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 10,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 10,
),
const Text(
"依赖类型:",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
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),
),
),
const SizedBox(
height: 10,
),
TextField(
controller: _nameController,
decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
hintText: "请输入名称",
DropdownMenuItem(
value: DepedencyEnum.Python3,
child: Text(DepedencyEnum.Python3.name),
),
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: Icon(
CupertinoIcons.add,
size: 20,
size: 24,
color: Colors.white,
),
),

View File

@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:qinglong_app/base/http/api.dart';
import 'package:qinglong_app/base/http/http.dart';
@@ -24,8 +23,7 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
final TextEditingController _commandController = TextEditingController();
final TextEditingController _cronController = TextEditingController();
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]*$";
FocusNode focusNode = FocusNode();
@override
void initState() {
@@ -38,6 +36,11 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
} else {
taskBean = TaskBean();
}
WidgetsBinding.instance?.addPostFrameCallback(
(timeStamp) {
focusNode.requestFocus();
},
);
}
@override
@@ -98,6 +101,7 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
height: 10,
),
TextField(
focusNode: focusNode,
controller: _nameController,
decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
@@ -133,9 +137,6 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
controller: _commandController,
maxLines: 4,
minLines: 1,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(scheduleCron)),
],
decoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
hintText: "请输入命令",
@@ -174,6 +175,15 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
),
autofocus: false,
),
const SizedBox(
height: 5,
),
const Text(
"定时的cron不校验,自己确保写的是正确的cron",
style: TextStyle(
fontSize: 12,
),
),
],
),
),
@@ -196,12 +206,14 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
return;
}
commitReal();
}
void commitReal() async {
taskBean.name = _nameController.text;
taskBean.command = _commandController.text;
taskBean.schedule = _cronController.text;
HttpResponse<NullResponse> response = await Api.addTask(
_nameController.text, _commandController.text, _cronController.text,
id: taskBean.sId);
HttpResponse<NullResponse> response = await Api.addTask(_nameController.text, _commandController.text, _cronController.text, id: taskBean.sId);
if (response.success) {
"操作成功".toast();