mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
add checkbox
This commit is contained in:
194
lib/module/env/add_env_page.dart
vendored
194
lib/module/env/add_env_page.dart
vendored
@@ -67,110 +67,112 @@ class _AddEnvPageState extends ConsumerState<AddEnvPage> {
|
||||
)
|
||||
],
|
||||
),
|
||||
body: 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,
|
||||
body: SingleChildScrollView(
|
||||
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 SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
controller: _nameController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入名称",
|
||||
const Text(
|
||||
"名称:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
controller: _valueController,
|
||||
maxLines: 8,
|
||||
minLines: 1,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入值",
|
||||
TextField(
|
||||
controller: _nameController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入名称",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
controller: _remarkController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入备注",
|
||||
const Text(
|
||||
"值:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
],
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
controller: _valueController,
|
||||
maxLines: 8,
|
||||
minLines: 1,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入值",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
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: _remarkController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入备注",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,14 +20,25 @@ class LoginPage extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
final TextEditingController _hostController =
|
||||
TextEditingController(text: getIt<UserInfoViewModel>().host);
|
||||
final TextEditingController _hostController = TextEditingController(text: getIt<UserInfoViewModel>().host);
|
||||
final TextEditingController _userNameController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
|
||||
bool rememberPassword = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (getIt<UserInfoViewModel>().userName != null && getIt<UserInfoViewModel>().userName!.isNotEmpty) {
|
||||
_userNameController.text = getIt<UserInfoViewModel>().userName!;
|
||||
rememberPassword = true;
|
||||
} else {
|
||||
rememberPassword = false;
|
||||
}
|
||||
if (getIt<UserInfoViewModel>().passWord != null && getIt<UserInfoViewModel>().passWord!.isNotEmpty) {
|
||||
_passwordController.text = getIt<UserInfoViewModel>().passWord!;
|
||||
}
|
||||
getIt<UserInfoViewModel>().updateToken("");
|
||||
}
|
||||
|
||||
@@ -96,7 +107,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 10,
|
||||
height: MediaQuery.of(context).size.height / 15,
|
||||
),
|
||||
const Text(
|
||||
"域名:",
|
||||
@@ -105,9 +116,6 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
@@ -120,7 +128,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"用户名:",
|
||||
@@ -129,9 +137,6 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
@@ -144,7 +149,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"密码:",
|
||||
@@ -153,9 +158,6 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
@@ -168,28 +170,41 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: rememberPassword,
|
||||
onChanged: (checked) {
|
||||
rememberPassword = checked ?? false;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"记住密码",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 80,
|
||||
child: IgnorePointer(
|
||||
ignoring: _hostController.text.isEmpty ||
|
||||
_userNameController.text.isEmpty ||
|
||||
_passwordController.text.isEmpty ||
|
||||
isLoading,
|
||||
ignoring: _hostController.text.isEmpty || _userNameController.text.isEmpty || _passwordController.text.isEmpty || isLoading,
|
||||
child: CupertinoButton(
|
||||
color: (_hostController.text.isNotEmpty &&
|
||||
_userNameController.text.isNotEmpty &&
|
||||
_passwordController.text.isNotEmpty &&
|
||||
!isLoading)
|
||||
? ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.buttonBgColor()
|
||||
: Theme.of(context)
|
||||
.primaryColor
|
||||
.withOpacity(0.4),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 5,
|
||||
),
|
||||
color:
|
||||
(_hostController.text.isNotEmpty && _userNameController.text.isNotEmpty && _passwordController.text.isNotEmpty && !isLoading)
|
||||
? ref.watch(themeProvider).themeColor.buttonBgColor()
|
||||
: Theme.of(context).primaryColor.withOpacity(0.4),
|
||||
child: isLoading
|
||||
? const CupertinoActivityIndicator()
|
||||
: const Text(
|
||||
@@ -199,12 +214,14 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (rememberPassword) {
|
||||
getIt<UserInfoViewModel>().updateUserName(_userNameController.text, _passwordController.text);
|
||||
}
|
||||
|
||||
Http.pushedLoginPage = false;
|
||||
Utils.hideKeyBoard(context);
|
||||
getIt<UserInfoViewModel>()
|
||||
.updateHost(_hostController.text);
|
||||
login(_userNameController.text,
|
||||
_passwordController.text);
|
||||
getIt<UserInfoViewModel>().updateHost(_hostController.text);
|
||||
login(_userNameController.text, _passwordController.text);
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -204,6 +204,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 40,
|
||||
child: CupertinoButton(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5,),
|
||||
color: ref.watch(themeProvider).themeColor.buttonBgColor(),
|
||||
child: const Text(
|
||||
"退出登录",
|
||||
|
||||
@@ -104,8 +104,7 @@ class _TaskPageState extends State<TaskPage> {
|
||||
if (_searchController.text.isEmpty ||
|
||||
(item.name?.contains(_searchController.text) ?? false) ||
|
||||
(item.command?.contains(_searchController.text) ?? false) ||
|
||||
(item.schedule?.contains(_searchController.text) ??
|
||||
false)) {
|
||||
(item.schedule?.contains(_searchController.text) ?? false)) {
|
||||
return TaskItemCell(item, ref);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
@@ -175,9 +174,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
child: Text(
|
||||
bean.status! == 1 ? "运行" : "停止运行",
|
||||
),
|
||||
trailingIcon: bean.status! == 1
|
||||
? CupertinoIcons.memories
|
||||
: CupertinoIcons.stop_circle,
|
||||
trailingIcon: bean.status! == 1 ? CupertinoIcons.memories : CupertinoIcons.stop_circle,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
startCron(context, ref);
|
||||
@@ -195,8 +192,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
child: const Text("编辑"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context)
|
||||
.pushNamed(Routes.routeAddTask, arguments: bean);
|
||||
Navigator.of(context).pushNamed(Routes.routeAddTask, arguments: bean);
|
||||
},
|
||||
trailingIcon: CupertinoIcons.pencil_outline,
|
||||
),
|
||||
@@ -206,9 +202,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
Navigator.of(context).pop();
|
||||
pinTask();
|
||||
},
|
||||
trailingIcon: bean.isPinned! == 0
|
||||
? CupertinoIcons.pin
|
||||
: CupertinoIcons.pin_slash,
|
||||
trailingIcon: bean.isPinned! == 0 ? CupertinoIcons.pin : CupertinoIcons.pin_slash,
|
||||
),
|
||||
QLCupertinoContextMenuAction(
|
||||
child: Text(bean.isDisabled! == 0 ? "禁用" : "启用"),
|
||||
@@ -217,9 +211,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
enableTask();
|
||||
},
|
||||
isDestructiveAction: true,
|
||||
trailingIcon: bean.isDisabled! == 0
|
||||
? Icons.dnd_forwardslash
|
||||
: Icons.check_circle_outline_sharp,
|
||||
trailingIcon: bean.isDisabled! == 0 ? Icons.dnd_forwardslash : Icons.check_circle_outline_sharp,
|
||||
),
|
||||
QLCupertinoContextMenuAction(
|
||||
child: const Text("删除"),
|
||||
@@ -233,19 +225,32 @@ class TaskItemCell extends StatelessWidget {
|
||||
],
|
||||
previewBuilder: (context, anima, child) {
|
||||
return IntrinsicWidth(
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
bean.name ?? "",
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: bean.isDisabled == 1
|
||||
? const Color(0xffF85152)
|
||||
: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 18,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
bean.name ?? "",
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
bean.isDisabled == 1
|
||||
? const Icon(
|
||||
Icons.dnd_forwardslash,
|
||||
size: 16,
|
||||
color: Colors.red,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -254,9 +259,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
color: bean.isPinned == 1
|
||||
? ref.watch(themeProvider).themeColor.pinColor()
|
||||
: Colors.transparent,
|
||||
color: bean.isPinned == 1 ? ref.watch(themeProvider).themeColor.pinColor() : Colors.transparent,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
vertical: 8,
|
||||
@@ -276,12 +279,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: bean.isDisabled == 1
|
||||
? const Color(0xffF85152)
|
||||
: ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.taskTitleColor(),
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
@@ -302,16 +300,11 @@ class TaskItemCell extends StatelessWidget {
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
(bean.lastExecutionTime == null ||
|
||||
bean.lastExecutionTime == 0)
|
||||
? "-"
|
||||
: Utils.formatMessageTime(
|
||||
bean.lastExecutionTime!),
|
||||
(bean.lastExecutionTime == null || bean.lastExecutionTime == 0) ? "-" : Utils.formatMessageTime(bean.lastExecutionTime!),
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color:
|
||||
ref.watch(themeProvider).themeColor.descColor(),
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
@@ -321,17 +314,31 @@ class TaskItemCell extends StatelessWidget {
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
bean.schedule ?? "",
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
fontSize: 12,
|
||||
Row(
|
||||
children: [
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
bean.schedule ?? "",
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
bean.isDisabled == 1
|
||||
? const Icon(
|
||||
Icons.dnd_forwardslash,
|
||||
size: 12,
|
||||
color: Colors.red,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -424,46 +431,6 @@ class TaskItemCell extends StatelessWidget {
|
||||
});
|
||||
}
|
||||
|
||||
more(BuildContext context, WidgetRef ref) {
|
||||
showCupertinoModalPopup<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => CupertinoActionSheet(
|
||||
title: const Text('更多操作'),
|
||||
actions: <CupertinoActionSheetAction>[
|
||||
CupertinoActionSheetAction(
|
||||
child: const Text('编辑'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context)
|
||||
.pushNamed(Routes.routeAddTask, arguments: bean);
|
||||
},
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
child: Text(bean.isDisabled! == 1 ? "启用" : "禁用"),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
enableTask();
|
||||
},
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
child: const Text('删除'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
delTask(context, ref);
|
||||
},
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
child: Text(bean.isPinned! == 0 ? "置顶" : "取消置顶"),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
pinTask();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void enableTask() {
|
||||
ref.read(taskProvider).enableTask(bean.sId!, bean.isDisabled!);
|
||||
}
|
||||
|
||||
@@ -33,9 +33,17 @@ class TaskViewModel extends BaseViewModel {
|
||||
list.sort((a, b) {
|
||||
return b.created!.compareTo(a.created!);
|
||||
});
|
||||
list.sort((a, b) {
|
||||
return b.isPinned!.compareTo(a.isPinned!);
|
||||
});
|
||||
// list.sort((a, b) {
|
||||
// return b.isPinned!.compareTo(a.isPinned!);
|
||||
// });
|
||||
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (list[i].isPinned == 1) {
|
||||
final TaskBean item = list.removeAt(i);
|
||||
list.insert(0, item);
|
||||
}
|
||||
}
|
||||
|
||||
running.clear();
|
||||
running.addAll(list.where((element) => element.status == 0));
|
||||
disabled.clear();
|
||||
|
||||
Reference in New Issue
Block a user