From a6208ea5f2840285a7698888f1b61919b40af063 Mon Sep 17 00:00:00 2001 From: jyuesong <425698907@qq.com> Date: Tue, 18 Jan 2022 10:10:03 +0800 Subject: [PATCH] add checkbox --- lib/base/sp_const.dart | 8 +- lib/base/theme.dart | 34 ++++- lib/base/userinfo_viewmodel.dart | 23 +++- lib/module/env/add_env_page.dart | 194 ++++++++++++++-------------- lib/module/login/login_page.dart | 83 +++++++----- lib/module/others/other_page.dart | 1 + lib/module/task/task_page.dart | 149 +++++++++------------ lib/module/task/task_viewmodel.dart | 14 +- 8 files changed, 273 insertions(+), 233 deletions(-) diff --git a/lib/base/sp_const.dart b/lib/base/sp_const.dart index c924c19..3767e14 100644 --- a/lib/base/sp_const.dart +++ b/lib/base/sp_const.dart @@ -1,3 +1,5 @@ -String sp_UserINfo = "userinfo"; -String sp_Host = "host"; -String sp_Theme = "dart_mode"; +String spUserInfo = "userinfo"; +String spHost = "host"; +String spUserName = "username"; +String spPassWord = "password"; +String spTheme = "dart_mode"; diff --git a/lib/base/theme.dart b/lib/base/theme.dart index 019cbef..5dce1c7 100644 --- a/lib/base/theme.dart +++ b/lib/base/theme.dart @@ -21,11 +21,11 @@ class ThemeViewModel extends ChangeNotifier { } bool isInDartMode() { - return SpUtil.getBool(sp_Theme, defValue: false); + return SpUtil.getBool(spTheme, defValue: false); } void changeThemeReal(bool dark, [bool notify = true]) { - SpUtil.putBool(sp_Theme, dark); + SpUtil.putBool(spTheme, dark); if (!dark) { currentTheme = lightTheme; themeColor = LightThemeColors(); @@ -39,7 +39,7 @@ class ThemeViewModel extends ChangeNotifier { } void changeTheme() { - changeThemeReal(!SpUtil.getBool(sp_Theme, defValue: false), true); + changeThemeReal(!SpUtil.getBool(spTheme, defValue: false), true); } } @@ -76,6 +76,20 @@ ThemeData darkTheme = ThemeData.dark().copyWith( secondary: _primaryColor, primary: _primaryColor, ), + toggleableActiveColor: _primaryColor, + checkboxTheme: CheckboxThemeData( + checkColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.disabled)) { + return Colors.transparent; + } + if (states.contains(MaterialState.selected)) { + return Colors.white; + } + return Colors.white; + }, + ), + ), ); ThemeData lightTheme = ThemeData.light().copyWith( brightness: Brightness.light, @@ -122,6 +136,20 @@ ThemeData lightTheme = ThemeData.light().copyWith( borderSide: BorderSide(color: _primaryColor), ), ), + toggleableActiveColor: _primaryColor, + checkboxTheme: CheckboxThemeData( + checkColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.disabled)) { + return Colors.transparent; + } + if (states.contains(MaterialState.selected)) { + return Colors.white; + } + return Colors.black; + }, + ), + ), ); abstract class ThemeColors { diff --git a/lib/base/userinfo_viewmodel.dart b/lib/base/userinfo_viewmodel.dart index 15ac951..e28b9ad 100644 --- a/lib/base/userinfo_viewmodel.dart +++ b/lib/base/userinfo_viewmodel.dart @@ -5,10 +5,14 @@ import 'sp_const.dart'; class UserInfoViewModel { String? _token; String? _host = ""; + String? _userName; + String? _passWord; UserInfoViewModel() { - String userInfoJson = SpUtil.getString(sp_UserINfo); - _host = SpUtil.getString(sp_Host, defValue: "http://49.234.59.95:5700"); + String userInfoJson = SpUtil.getString(spUserInfo); + _userName = SpUtil.getString(spUserName); + _passWord = SpUtil.getString(spPassWord); + _host = SpUtil.getString(spHost, defValue: "http://49.234.59.95:5700"); if (userInfoJson.isNotEmpty) { _token = userInfoJson; } @@ -16,18 +20,29 @@ class UserInfoViewModel { void updateToken(String token) { _token = token; - SpUtil.putString(sp_UserINfo, token); + SpUtil.putString(spUserInfo, token); + } + + void updateUserName(String userName, String password) { + _userName = userName; + _passWord = password; + SpUtil.putString(spUserName, userName); + SpUtil.putString(spPassWord, password); } void updateHost(String host) { _host = host; - SpUtil.putString(sp_Host, host); + SpUtil.putString(spHost, host); } String? get token => _token; String? get host => _host; + String? get userName => _userName; + + String? get passWord => _passWord; + bool isLogined() { return token != null && token!.isNotEmpty; } diff --git a/lib/module/env/add_env_page.dart b/lib/module/env/add_env_page.dart index 0a6c131..10d7353 100644 --- a/lib/module/env/add_env_page.dart +++ b/lib/module/env/add_env_page.dart @@ -67,110 +67,112 @@ class _AddEnvPageState extends ConsumerState { ) ], ), - 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, + ), + ], + ), + ), + ], + ), ), ); } diff --git a/lib/module/login/login_page.dart b/lib/module/login/login_page.dart index 788e547..93cf72b 100644 --- a/lib/module/login/login_page.dart +++ b/lib/module/login/login_page.dart @@ -20,14 +20,25 @@ class LoginPage extends ConsumerStatefulWidget { } class _LoginPageState extends ConsumerState { - final TextEditingController _hostController = - TextEditingController(text: getIt().host); + final TextEditingController _hostController = TextEditingController(text: getIt().host); final TextEditingController _userNameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); + bool rememberPassword = false; + @override void initState() { super.initState(); + + if (getIt().userName != null && getIt().userName!.isNotEmpty) { + _userNameController.text = getIt().userName!; + rememberPassword = true; + } else { + rememberPassword = false; + } + if (getIt().passWord != null && getIt().passWord!.isNotEmpty) { + _passwordController.text = getIt().passWord!; + } getIt().updateToken(""); } @@ -96,7 +107,7 @@ class _LoginPageState extends ConsumerState { ), ), 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 { fontWeight: FontWeight.w600, ), ), - const SizedBox( - height: 10, - ), TextField( onChanged: (_) { setState(() {}); @@ -120,7 +128,7 @@ class _LoginPageState extends ConsumerState { autofocus: false, ), const SizedBox( - height: 20, + height: 15, ), const Text( "用户名:", @@ -129,9 +137,6 @@ class _LoginPageState extends ConsumerState { fontWeight: FontWeight.w600, ), ), - const SizedBox( - height: 10, - ), TextField( onChanged: (_) { setState(() {}); @@ -144,7 +149,7 @@ class _LoginPageState extends ConsumerState { autofocus: false, ), const SizedBox( - height: 20, + height: 15, ), const Text( "密码:", @@ -153,9 +158,6 @@ class _LoginPageState extends ConsumerState { fontWeight: FontWeight.w600, ), ), - const SizedBox( - height: 10, - ), TextField( onChanged: (_) { setState(() {}); @@ -168,28 +170,41 @@ class _LoginPageState extends ConsumerState { ), 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 { ), ), onPressed: () { + if (rememberPassword) { + getIt().updateUserName(_userNameController.text, _passwordController.text); + } + Http.pushedLoginPage = false; Utils.hideKeyBoard(context); - getIt() - .updateHost(_hostController.text); - login(_userNameController.text, - _passwordController.text); + getIt().updateHost(_hostController.text); + login(_userNameController.text, _passwordController.text); }), ), ), diff --git a/lib/module/others/other_page.dart b/lib/module/others/other_page.dart index 0c9a11f..f9f9352 100644 --- a/lib/module/others/other_page.dart +++ b/lib/module/others/other_page.dart @@ -204,6 +204,7 @@ class _OtherPageState extends ConsumerState { 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( "退出登录", diff --git a/lib/module/task/task_page.dart b/lib/module/task/task_page.dart index 3e74d43..0611c32 100644 --- a/lib/module/task/task_page.dart +++ b/lib/module/task/task_page.dart @@ -104,8 +104,7 @@ class _TaskPageState extends State { 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( - context: context, - builder: (BuildContext context) => CupertinoActionSheet( - title: const Text('更多操作'), - actions: [ - 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!); } diff --git a/lib/module/task/task_viewmodel.dart b/lib/module/task/task_viewmodel.dart index eb8db83..90c05c5 100644 --- a/lib/module/task/task_viewmodel.dart +++ b/lib/module/task/task_viewmodel.dart @@ -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();