mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
Merge branch 'dev'
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,3 +1,13 @@
|
|||||||
|
## 1.0.4
|
||||||
|
* 增加主题切换功能,各种颜色主题随意切换
|
||||||
|
* 修改无法停止任务的bug
|
||||||
|
* 修改脚本管理页面json解析失败的bug
|
||||||
|
* 修改变更配置文件没有及时刷新UI的bug
|
||||||
|
* 增加版本更新提醒功能(需要手机能联通github)
|
||||||
|
* 登录页面长按青龙logo可以呼出网络请求日志,再次长按可关闭
|
||||||
|
* 打开系统最近任务时展示APP的名称
|
||||||
|
* 优化使用体验
|
||||||
|
|
||||||
## 1.0.3
|
## 1.0.3
|
||||||
|
|
||||||
* 解决2.10.12及以下版本无法登录的问题
|
* 解决2.10.12及以下版本无法登录的问题
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ iOS端暂无上架打算,用户自行下载main分支源码编译安装
|
|||||||
|
|
||||||
|
|
||||||
<p float="left">
|
<p float="left">
|
||||||
|
<img src="./art/14.jpg" width="200" />
|
||||||
<img src="./art/1.jpg" width="200" />
|
<img src="./art/1.jpg" width="200" />
|
||||||
<img src="./art/8.jpg" width="200" />
|
|
||||||
<img src="./art/9.jpg" width="200" />
|
<img src="./art/9.jpg" width="200" />
|
||||||
</p>
|
</p>
|
||||||
<p float="left">
|
<p float="left">
|
||||||
@@ -35,9 +35,9 @@ iOS端暂无上架打算,用户自行下载main分支源码编译安装
|
|||||||
|
|
||||||
<p float="left">
|
<p float="left">
|
||||||
<img src="./art/13.jpg" width="200" />
|
<img src="./art/13.jpg" width="200" />
|
||||||
|
<img src="./art/8.jpg" width="200" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
### 不支持的功能
|
### 不支持的功能
|
||||||
|
|
||||||
>* 应用设置
|
>* 应用设置
|
||||||
>* 通知设置
|
>* 通知设置
|
||||||
|
|||||||
BIN
art/14.jpg
Normal file
BIN
art/14.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 168 KiB |
BIN
assets/images/update_bg_app_top.png
Normal file
BIN
assets/images/update_bg_app_top.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
BIN
assets/images/update_ic_close.png
Normal file
BIN
assets/images/update_ic_close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -5,15 +5,21 @@ PODS:
|
|||||||
- Toast
|
- Toast
|
||||||
- move_to_background (0.0.1):
|
- move_to_background (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- package_info_plus (0.4.5):
|
||||||
|
- Flutter
|
||||||
- shared_preferences_ios (0.0.1):
|
- shared_preferences_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Toast (4.0.0)
|
- Toast (4.0.0)
|
||||||
|
- url_launcher_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
- move_to_background (from `.symlinks/plugins/move_to_background/ios`)
|
- move_to_background (from `.symlinks/plugins/move_to_background/ios`)
|
||||||
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
||||||
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
@@ -26,15 +32,21 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/fluttertoast/ios"
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
move_to_background:
|
move_to_background:
|
||||||
:path: ".symlinks/plugins/move_to_background/ios"
|
:path: ".symlinks/plugins/move_to_background/ios"
|
||||||
|
package_info_plus:
|
||||||
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
shared_preferences_ios:
|
shared_preferences_ios:
|
||||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||||
|
url_launcher_ios:
|
||||||
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||||
fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58
|
fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58
|
||||||
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
|
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
|
||||||
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
shared_preferences_ios: aef470a42dc4675a1cdd50e3158b42e3d1232b32
|
shared_preferences_ios: aef470a42dc4675a1cdd50e3158b42e3d1232b32
|
||||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
|
url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af
|
||||||
|
|
||||||
PODFILE CHECKSUM: aea2ed8a4b05dec076f6f7cea39202b1133ed51c
|
PODFILE CHECKSUM: aea2ed8a4b05dec076f6f7cea39202b1133ed51c
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class Api {
|
|||||||
|
|
||||||
static Future<HttpResponse<NullResponse>> stopTasks(List<String> crons) async {
|
static Future<HttpResponse<NullResponse>> stopTasks(List<String> crons) async {
|
||||||
return await Http.put<NullResponse>(
|
return await Http.put<NullResponse>(
|
||||||
Url.runTasks,
|
Url.stopTasks,
|
||||||
crons,
|
crons,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,4 +76,6 @@ class Url {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String checkUpdateUrl = "https://raw.githubusercontent.com/qinglong-app/qinglong_app/main/version";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import 'package:qinglong_app/module/others/scripts/script_edit_page.dart';
|
|||||||
import 'package:qinglong_app/module/others/scripts/script_page.dart';
|
import 'package:qinglong_app/module/others/scripts/script_page.dart';
|
||||||
import 'package:qinglong_app/module/others/task_log/task_log_detail_page.dart';
|
import 'package:qinglong_app/module/others/task_log/task_log_detail_page.dart';
|
||||||
import 'package:qinglong_app/module/others/task_log/task_log_page.dart';
|
import 'package:qinglong_app/module/others/task_log/task_log_page.dart';
|
||||||
|
import 'package:qinglong_app/module/others/theme_page.dart';
|
||||||
import 'package:qinglong_app/module/others/update_password_page.dart';
|
import 'package:qinglong_app/module/others/update_password_page.dart';
|
||||||
import 'package:qinglong_app/module/task/add_task_page.dart';
|
import 'package:qinglong_app/module/task/add_task_page.dart';
|
||||||
import 'package:qinglong_app/module/task/task_bean.dart';
|
import 'package:qinglong_app/module/task/task_bean.dart';
|
||||||
@@ -39,6 +40,7 @@ class Routes {
|
|||||||
static const String routeDependency = "/Dependency";
|
static const String routeDependency = "/Dependency";
|
||||||
static const String routeUpdatePassword = "/updatePassword";
|
static const String routeUpdatePassword = "/updatePassword";
|
||||||
static const String routeAbout = "/about";
|
static const String routeAbout = "/about";
|
||||||
|
static const String routeTheme = "/theme";
|
||||||
|
|
||||||
static Route<dynamic>? generateRoute(RouteSettings settings) {
|
static Route<dynamic>? generateRoute(RouteSettings settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
@@ -56,7 +58,8 @@ class Routes {
|
|||||||
return CupertinoPageRoute(builder: (context) => const AddTaskPage());
|
return CupertinoPageRoute(builder: (context) => const AddTaskPage());
|
||||||
}
|
}
|
||||||
case routeAddDependency:
|
case routeAddDependency:
|
||||||
return CupertinoPageRoute(builder: (context) => const AddDependencyPage());
|
return CupertinoPageRoute(
|
||||||
|
builder: (context) => const AddDependencyPage());
|
||||||
case routeAddEnv:
|
case routeAddEnv:
|
||||||
if (settings.arguments != null) {
|
if (settings.arguments != null) {
|
||||||
return CupertinoPageRoute(
|
return CupertinoPageRoute(
|
||||||
@@ -122,6 +125,10 @@ class Routes {
|
|||||||
return CupertinoPageRoute(
|
return CupertinoPageRoute(
|
||||||
builder: (context) => const AboutPage(),
|
builder: (context) => const AboutPage(),
|
||||||
);
|
);
|
||||||
|
case routeTheme:
|
||||||
|
return CupertinoPageRoute(
|
||||||
|
builder: (context) => const ThemePage(),
|
||||||
|
);
|
||||||
case routeScriptUpdate:
|
case routeScriptUpdate:
|
||||||
return CupertinoPageRoute(
|
return CupertinoPageRoute(
|
||||||
builder: (context) => ScriptEditPage(
|
builder: (context) => ScriptEditPage(
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ String spUserName = "username";
|
|||||||
String spPassWord = "password";
|
String spPassWord = "password";
|
||||||
String spTheme = "dart_mode";
|
String spTheme = "dart_mode";
|
||||||
String spSecretLogined = "secret_logined";
|
String spSecretLogined = "secret_logined";
|
||||||
|
String spCustomColor = "customColor";
|
||||||
|
|||||||
@@ -3,21 +3,25 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:qinglong_app/base/sp_const.dart';
|
import 'package:qinglong_app/base/sp_const.dart';
|
||||||
|
import 'package:qinglong_app/base/userinfo_viewmodel.dart';
|
||||||
|
import 'package:qinglong_app/main.dart';
|
||||||
import 'package:qinglong_app/utils/codeeditor_theme.dart';
|
import 'package:qinglong_app/utils/codeeditor_theme.dart';
|
||||||
import 'package:qinglong_app/utils/sp_utils.dart';
|
import 'package:qinglong_app/utils/sp_utils.dart';
|
||||||
|
|
||||||
var themeProvider = ChangeNotifierProvider((ref) => ThemeViewModel());
|
var themeProvider = ChangeNotifierProvider((ref) => ThemeViewModel());
|
||||||
const Color _primaryColor = Color(0xFF299343);
|
Color _primaryColor = const Color(0xFF299343);
|
||||||
|
|
||||||
get primaryColor => _primaryColor;
|
|
||||||
|
|
||||||
class ThemeViewModel extends ChangeNotifier {
|
class ThemeViewModel extends ChangeNotifier {
|
||||||
ThemeData currentTheme = lightTheme;
|
late ThemeData currentTheme;
|
||||||
|
|
||||||
bool _isInDarkMode = false;
|
bool _isInDarkMode = false;
|
||||||
|
Color primaryColor = const Color(0xFF299343);
|
||||||
|
|
||||||
ThemeColors themeColor = LightThemeColors();
|
ThemeColors themeColor = LightThemeColors();
|
||||||
|
|
||||||
ThemeViewModel() {
|
ThemeViewModel() {
|
||||||
|
_primaryColor = Color(getIt<UserInfoViewModel>().primaryColor);
|
||||||
|
primaryColor = Color(getIt<UserInfoViewModel>().primaryColor);
|
||||||
var brightness = SchedulerBinding.instance!.window.platformBrightness;
|
var brightness = SchedulerBinding.instance!.window.platformBrightness;
|
||||||
_isInDarkMode = brightness == Brightness.dark;
|
_isInDarkMode = brightness == Brightness.dark;
|
||||||
changeThemeReal(_isInDarkMode, false);
|
changeThemeReal(_isInDarkMode, false);
|
||||||
@@ -31,10 +35,10 @@ class ThemeViewModel extends ChangeNotifier {
|
|||||||
_isInDarkMode = dark;
|
_isInDarkMode = dark;
|
||||||
SpUtil.putBool(spTheme, dark);
|
SpUtil.putBool(spTheme, dark);
|
||||||
if (!dark) {
|
if (!dark) {
|
||||||
currentTheme = lightTheme;
|
currentTheme = getLightTheme();
|
||||||
themeColor = LightThemeColors();
|
themeColor = LightThemeColors();
|
||||||
} else {
|
} else {
|
||||||
currentTheme = darkTheme;
|
currentTheme = getDartTheme();
|
||||||
themeColor = DartThemeColors();
|
themeColor = DartThemeColors();
|
||||||
}
|
}
|
||||||
if (notify) {
|
if (notify) {
|
||||||
@@ -44,149 +48,161 @@ class ThemeViewModel extends ChangeNotifier {
|
|||||||
|
|
||||||
get darkMode => _isInDarkMode;
|
get darkMode => _isInDarkMode;
|
||||||
|
|
||||||
|
void changePrimaryColor(Color color) {
|
||||||
|
_primaryColor = color;
|
||||||
|
primaryColor = color;
|
||||||
|
getIt<UserInfoViewModel>().updateCustomColor(color.value);
|
||||||
|
changeThemeReal(SpUtil.getBool(spTheme, defValue: false), true);
|
||||||
|
}
|
||||||
|
|
||||||
void changeTheme() {
|
void changeTheme() {
|
||||||
changeThemeReal(!SpUtil.getBool(spTheme, defValue: false), true);
|
changeThemeReal(!SpUtil.getBool(spTheme, defValue: false), true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ThemeData darkTheme = ThemeData.dark().copyWith(
|
ThemeData getLightTheme() {
|
||||||
brightness: Brightness.dark,
|
return ThemeData.light().copyWith(
|
||||||
primaryColor: const Color(0xffffffff),
|
brightness: Brightness.light,
|
||||||
scaffoldBackgroundColor: Colors.black,
|
primaryColor: _primaryColor,
|
||||||
appBarTheme: const AppBarTheme(
|
colorScheme: ColorScheme.light(
|
||||||
backgroundColor: Colors.black,
|
secondary: _primaryColor,
|
||||||
titleTextStyle: TextStyle(
|
primary: _primaryColor,
|
||||||
color: Colors.white,
|
),
|
||||||
fontSize: 18,
|
scaffoldBackgroundColor: const Color(0xfff5f5f5),
|
||||||
),
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
),
|
labelStyle: TextStyle(color: _primaryColor),
|
||||||
inputDecorationTheme: const InputDecorationTheme(
|
focusedBorder: UnderlineInputBorder(
|
||||||
labelStyle: TextStyle(color: _primaryColor),
|
borderSide: BorderSide(
|
||||||
focusedBorder: UnderlineInputBorder(
|
color: _primaryColor,
|
||||||
borderSide: BorderSide(
|
),
|
||||||
|
),
|
||||||
|
border: const UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xff999999),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: const UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xff999999),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
appBarTheme: AppBarTheme(
|
||||||
|
backgroundColor: _primaryColor,
|
||||||
|
titleTextStyle: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
||||||
|
selectedItemColor: _primaryColor,
|
||||||
|
),
|
||||||
|
buttonTheme: ButtonThemeData(
|
||||||
|
buttonColor: _primaryColor,
|
||||||
|
),
|
||||||
|
progressIndicatorTheme: ProgressIndicatorThemeData(
|
||||||
color: _primaryColor,
|
color: _primaryColor,
|
||||||
),
|
),
|
||||||
),
|
tabBarTheme: TabBarTheme(
|
||||||
border: UnderlineInputBorder(
|
labelStyle: const TextStyle(
|
||||||
borderSide: BorderSide(
|
fontSize: 14,
|
||||||
color: Color(0xff999999),
|
),
|
||||||
|
unselectedLabelStyle: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
labelColor: _primaryColor,
|
||||||
|
unselectedLabelColor: const Color(0xff999999),
|
||||||
|
indicator: UnderlineTabIndicator(
|
||||||
|
borderSide: BorderSide(color: _primaryColor),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
toggleableActiveColor: _primaryColor,
|
||||||
enabledBorder: UnderlineInputBorder(
|
checkboxTheme: CheckboxThemeData(
|
||||||
borderSide: BorderSide(
|
checkColor: MaterialStateProperty.resolveWith(
|
||||||
color: Color(0xff999999),
|
(Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return Colors.transparent;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return Colors.white;
|
||||||
|
}
|
||||||
|
return Colors.black;
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
cupertinoOverrideTheme: NoDefaultCupertinoThemeData(
|
||||||
),
|
brightness: Brightness.light,
|
||||||
tabBarTheme: const TabBarTheme(
|
primaryColor: _primaryColor,
|
||||||
labelStyle: TextStyle(
|
scaffoldBackgroundColor: const Color(0xfff5f5f5),
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
unselectedLabelStyle: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
labelColor: Color(0xffffffff),
|
|
||||||
unselectedLabelColor: Color(0xff999999),
|
|
||||||
),
|
|
||||||
colorScheme: const ColorScheme.light(
|
|
||||||
secondary: _primaryColor,
|
|
||||||
primary: _primaryColor,
|
|
||||||
),
|
|
||||||
toggleableActiveColor: _primaryColor,
|
|
||||||
checkboxTheme: CheckboxThemeData(
|
|
||||||
checkColor: MaterialStateProperty.resolveWith(
|
|
||||||
(Set<MaterialState> states) {
|
|
||||||
if (states.contains(MaterialState.disabled)) {
|
|
||||||
return Colors.transparent;
|
|
||||||
}
|
|
||||||
if (states.contains(MaterialState.selected)) {
|
|
||||||
return Colors.white;
|
|
||||||
}
|
|
||||||
return Colors.white;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
cupertinoOverrideTheme: const NoDefaultCupertinoThemeData(
|
|
||||||
brightness: Brightness.dark,
|
|
||||||
primaryColor: Color(0xffffffff),
|
|
||||||
scaffoldBackgroundColor: Colors.black,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
ThemeData lightTheme = ThemeData.light().copyWith(
|
|
||||||
brightness: Brightness.light,
|
|
||||||
primaryColor: _primaryColor,
|
|
||||||
colorScheme: const ColorScheme.light(
|
|
||||||
secondary: _primaryColor,
|
|
||||||
primary: _primaryColor,
|
|
||||||
),
|
|
||||||
scaffoldBackgroundColor: const Color(0xfff5f5f5),
|
|
||||||
inputDecorationTheme: const InputDecorationTheme(
|
|
||||||
labelStyle: TextStyle(color: _primaryColor),
|
|
||||||
focusedBorder: UnderlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: _primaryColor,
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
border: UnderlineInputBorder(
|
}
|
||||||
borderSide: BorderSide(
|
|
||||||
color: Color(0xff999999),
|
ThemeData getDartTheme() {
|
||||||
|
return ThemeData.dark().copyWith(
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
primaryColor: const Color(0xffffffff),
|
||||||
|
scaffoldBackgroundColor: Colors.black,
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
enabledBorder: UnderlineInputBorder(
|
labelStyle: TextStyle(color: _primaryColor),
|
||||||
borderSide: BorderSide(
|
focusedBorder: UnderlineInputBorder(
|
||||||
color: Color(0xff999999),
|
borderSide: BorderSide(
|
||||||
|
color: _primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
border: const UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xff999999),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: const UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xff999999),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
tabBarTheme: const TabBarTheme(
|
||||||
),
|
labelStyle: TextStyle(
|
||||||
appBarTheme: const AppBarTheme(
|
fontSize: 14,
|
||||||
backgroundColor: _primaryColor,
|
),
|
||||||
titleTextStyle: TextStyle(
|
unselectedLabelStyle: TextStyle(
|
||||||
color: Colors.white,
|
fontSize: 14,
|
||||||
fontSize: 18,
|
),
|
||||||
),
|
labelColor: Color(0xffffffff),
|
||||||
),
|
unselectedLabelColor: Color(0xff999999),
|
||||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
),
|
||||||
selectedItemColor: _primaryColor,
|
colorScheme: ColorScheme.light(
|
||||||
),
|
secondary: _primaryColor,
|
||||||
buttonTheme: const ButtonThemeData(
|
primary: _primaryColor,
|
||||||
buttonColor: _primaryColor,
|
),
|
||||||
),
|
toggleableActiveColor: _primaryColor,
|
||||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
checkboxTheme: CheckboxThemeData(
|
||||||
color: _primaryColor,
|
checkColor: MaterialStateProperty.resolveWith(
|
||||||
),
|
(Set<MaterialState> states) {
|
||||||
tabBarTheme: const TabBarTheme(
|
if (states.contains(MaterialState.disabled)) {
|
||||||
labelStyle: TextStyle(
|
return Colors.transparent;
|
||||||
fontSize: 14,
|
}
|
||||||
),
|
if (states.contains(MaterialState.selected)) {
|
||||||
unselectedLabelStyle: TextStyle(
|
return Colors.white;
|
||||||
fontSize: 14,
|
}
|
||||||
),
|
return Colors.white;
|
||||||
labelColor: _primaryColor,
|
},
|
||||||
unselectedLabelColor: Color(0xff999999),
|
),
|
||||||
indicator: UnderlineTabIndicator(
|
),
|
||||||
borderSide: BorderSide(color: _primaryColor),
|
cupertinoOverrideTheme: const NoDefaultCupertinoThemeData(
|
||||||
),
|
brightness: Brightness.dark,
|
||||||
),
|
primaryColor: Color(0xffffffff),
|
||||||
toggleableActiveColor: _primaryColor,
|
scaffoldBackgroundColor: Colors.black,
|
||||||
checkboxTheme: CheckboxThemeData(
|
),
|
||||||
checkColor: MaterialStateProperty.resolveWith(
|
);
|
||||||
(Set<MaterialState> states) {
|
}
|
||||||
if (states.contains(MaterialState.disabled)) {
|
}
|
||||||
return Colors.transparent;
|
|
||||||
}
|
|
||||||
if (states.contains(MaterialState.selected)) {
|
|
||||||
return Colors.white;
|
|
||||||
}
|
|
||||||
return Colors.black;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
cupertinoOverrideTheme: const NoDefaultCupertinoThemeData(
|
|
||||||
brightness: Brightness.light,
|
|
||||||
primaryColor: _primaryColor,
|
|
||||||
scaffoldBackgroundColor: Color(0xfff5f5f5),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
abstract class ThemeColors {
|
abstract class ThemeColors {
|
||||||
Color settingBgColor();
|
Color settingBgColor();
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ class UserInfoViewModel {
|
|||||||
String? _userName;
|
String? _userName;
|
||||||
String? _passWord;
|
String? _passWord;
|
||||||
bool _useSecertLogined = false;
|
bool _useSecertLogined = false;
|
||||||
|
int _primaryColor = 0xFF299343;
|
||||||
|
|
||||||
UserInfoViewModel() {
|
UserInfoViewModel() {
|
||||||
String userInfoJson = SpUtil.getString(spUserInfo);
|
String userInfoJson = SpUtil.getString(spUserInfo);
|
||||||
_userName = SpUtil.getString(spUserName);
|
_userName = SpUtil.getString(spUserName);
|
||||||
_passWord = SpUtil.getString(spPassWord);
|
_passWord = SpUtil.getString(spPassWord);
|
||||||
|
_primaryColor = SpUtil.getInt(spCustomColor, defValue: 0xFF299343);
|
||||||
|
|
||||||
_useSecertLogined = SpUtil.getBool(spSecretLogined, defValue: false);
|
_useSecertLogined = SpUtil.getBool(spSecretLogined, defValue: false);
|
||||||
_host = SpUtil.getString(spHost, defValue: '');
|
_host = SpUtil.getString(spHost, defValue: '');
|
||||||
@@ -39,6 +41,11 @@ class UserInfoViewModel {
|
|||||||
SpUtil.putBool(spSecretLogined, _useSecertLogined);
|
SpUtil.putBool(spSecretLogined, _useSecertLogined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateCustomColor(int color) {
|
||||||
|
_primaryColor = color;
|
||||||
|
SpUtil.putInt(spCustomColor, color);
|
||||||
|
}
|
||||||
|
|
||||||
void updateHost(String host) {
|
void updateHost(String host) {
|
||||||
_host = host;
|
_host = host;
|
||||||
SpUtil.putString(spHost, host);
|
SpUtil.putString(spHost, host);
|
||||||
@@ -54,6 +61,8 @@ class UserInfoViewModel {
|
|||||||
|
|
||||||
bool get useSecretLogined => _useSecertLogined;
|
bool get useSecretLogined => _useSecertLogined;
|
||||||
|
|
||||||
|
int get primaryColor => _primaryColor;
|
||||||
|
|
||||||
bool isLogined() {
|
bool isLogined() {
|
||||||
return token != null && token!.isNotEmpty;
|
return token != null && token!.isNotEmpty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ class QlAppState extends ConsumerState<QlApp> {
|
|||||||
child: MediaQuery(
|
child: MediaQuery(
|
||||||
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window).copyWith(textScaleFactor: 1,),
|
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window).copyWith(textScaleFactor: 1,),
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
locale: const Locale('zh', 'cn'),
|
title: "青龙",
|
||||||
|
locale: const Locale('zh', 'CN'),
|
||||||
navigatorKey: navigatorState,
|
navigatorKey: navigatorState,
|
||||||
theme: ref.watch<ThemeViewModel>(themeProvider).currentTheme,
|
theme: ref.watch<ThemeViewModel>(themeProvider).currentTheme,
|
||||||
onGenerateRoute: (setting) {
|
onGenerateRoute: (setting) {
|
||||||
@@ -65,9 +66,6 @@ class QlAppState extends ConsumerState<QlApp> {
|
|||||||
},
|
},
|
||||||
home: Builder(
|
home: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
if (!kReleaseMode) {
|
|
||||||
showDebugBtn(context, btnColor: Colors.blue);
|
|
||||||
}
|
|
||||||
return getIt<UserInfoViewModel>().isLogined() ? const HomePage() : const LoginPage();
|
return getIt<UserInfoViewModel>().isLogined() ? const HomePage() : const LoginPage();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -49,7 +49,7 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
|
|||||||
if (response.success) {
|
if (response.success) {
|
||||||
"提交成功".toast();
|
"提交成功".toast();
|
||||||
ref.read(configProvider).loadContent(widget.title);
|
ref.read(configProvider).loadContent(widget.title);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop(widget.title);
|
||||||
} else {
|
} else {
|
||||||
(response.message ?? "").toast();
|
(response.message ?? "").toast();
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
|
|||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: node,
|
focusNode: node,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.read(themeProvider).themeColor.descColor(),
|
color: ref.read(themeProvider).themeColor.titleColor(),
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:qinglong_app/base/base_state_widget.dart';
|
|||||||
import 'package:qinglong_app/base/routes.dart';
|
import 'package:qinglong_app/base/routes.dart';
|
||||||
import 'package:qinglong_app/base/theme.dart';
|
import 'package:qinglong_app/base/theme.dart';
|
||||||
import 'package:qinglong_app/base/ui/abs_underline_tabindicator.dart';
|
import 'package:qinglong_app/base/ui/abs_underline_tabindicator.dart';
|
||||||
|
import 'package:qinglong_app/base/ui/empty_widget.dart';
|
||||||
import 'package:qinglong_app/main.dart';
|
import 'package:qinglong_app/main.dart';
|
||||||
|
|
||||||
import 'config_viewmodel.dart';
|
import 'config_viewmodel.dart';
|
||||||
@@ -29,6 +30,9 @@ class ConfigPageState extends State<ConfigPage>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseStateWidget<ConfigViewModel>(
|
return BaseStateWidget<ConfigViewModel>(
|
||||||
builder: (ref, model, child) {
|
builder: (ref, model, child) {
|
||||||
|
if (model.list.isEmpty) {
|
||||||
|
return const EmptyWidget();
|
||||||
|
}
|
||||||
_tabController ??=
|
_tabController ??=
|
||||||
TabController(length: model.list.length, vsync: this);
|
TabController(length: model.list.length, vsync: this);
|
||||||
|
|
||||||
@@ -89,6 +93,11 @@ class ConfigPageState extends State<ConfigPage>
|
|||||||
"title": ref.read(configProvider).list[_tabController?.index ?? 0].title,
|
"title": ref.read(configProvider).list[_tabController?.index ?? 0].title,
|
||||||
"content": ref.read(configProvider).content[
|
"content": ref.read(configProvider).content[
|
||||||
ref.read(configProvider).list[_tabController?.index ?? 0].title]
|
ref.read(configProvider).list[_tabController?.index ?? 0].title]
|
||||||
|
}).then((value) async {
|
||||||
|
if (value != null && (value as String).isNotEmpty) {
|
||||||
|
await ref.read(configProvider).loadContent(value);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
lib/module/env/env_bean.dart
vendored
2
lib/module/env/env_bean.dart
vendored
@@ -15,7 +15,7 @@ class EnvBean {
|
|||||||
EnvBean.fromJson(Map<String, dynamic> json) {
|
EnvBean.fromJson(Map<String, dynamic> json) {
|
||||||
value = json['value'];
|
value = json['value'];
|
||||||
sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : "");
|
sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : "");
|
||||||
created = json['created'];
|
created = int.tryParse(json['created'].toString());
|
||||||
status = json['status'];
|
status = json['status'];
|
||||||
timestamp = json['timestamp'];
|
timestamp = json['timestamp'];
|
||||||
name = json['name'];
|
name = json['name'];
|
||||||
|
|||||||
2
lib/module/env/env_detail_page.dart
vendored
2
lib/module/env/env_detail_page.dart
vendored
@@ -249,7 +249,7 @@ class _TaskDetailPageState extends ConsumerState<EnvDetailPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|||||||
27
lib/module/env/env_page.dart
vendored
27
lib/module/env/env_page.dart
vendored
@@ -238,13 +238,24 @@ class EnvItemCell extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(color: primaryColor, width: 1),
|
border: Border.all(color: ref.watch(themeProvider).primaryColor, width: 1),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
"$index",
|
"$index",
|
||||||
style: TextStyle(color: primaryColor, fontSize: 12),
|
style: TextStyle(color: ref.watch(themeProvider).primaryColor, fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 5,
|
||||||
|
),
|
||||||
|
bean.status == 1
|
||||||
|
? const Icon(
|
||||||
|
Icons.dnd_forwardslash,
|
||||||
|
size: 12,
|
||||||
|
color: Colors.red,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 5,
|
width: 5,
|
||||||
),
|
),
|
||||||
@@ -261,16 +272,6 @@ class EnvItemCell extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
|
||||||
width: 5,
|
|
||||||
),
|
|
||||||
bean.status == 1
|
|
||||||
? const Icon(
|
|
||||||
Icons.dnd_forwardslash,
|
|
||||||
size: 12,
|
|
||||||
color: Colors.red,
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -331,7 +332,7 @@ class EnvItemCell extends StatelessWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:qinglong_app/module/env/env_page.dart';
|
|||||||
import 'package:qinglong_app/module/others/other_page.dart';
|
import 'package:qinglong_app/module/others/other_page.dart';
|
||||||
import 'package:qinglong_app/module/task/task_page.dart';
|
import 'package:qinglong_app/module/task/task_page.dart';
|
||||||
import 'package:move_to_background/move_to_background.dart';
|
import 'package:move_to_background/move_to_background.dart';
|
||||||
|
import 'package:qinglong_app/utils/update_utils.dart';
|
||||||
|
|
||||||
class HomePage extends ConsumerStatefulWidget {
|
class HomePage extends ConsumerStatefulWidget {
|
||||||
const HomePage({Key? key}) : super(key: key);
|
const HomePage({Key? key}) : super(key: key);
|
||||||
@@ -30,6 +31,9 @@ class _HomePageState extends ConsumerState<HomePage> {
|
|||||||
initTitles();
|
initTitles();
|
||||||
_title = titles[0].title;
|
_title = titles[0].title;
|
||||||
super.initState();
|
super.initState();
|
||||||
|
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||||
|
update();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -185,6 +189,16 @@ class _HomePageState extends ConsumerState<HomePage> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
String? result = await UpdateUtils().checkUpdate();
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
UpdateDialog updateDialog = UpdateDialog(context, title: "发现新版本", updateContent: "版本号:v$result", onUpdate: () {
|
||||||
|
UpdateUtils.launchURL(result);
|
||||||
|
});
|
||||||
|
updateDialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IndexBean {
|
class IndexBean {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class LoginBean {
|
|||||||
token = json['token'];
|
token = json['token'];
|
||||||
lastip = json['lastip'];
|
lastip = json['lastip'];
|
||||||
lastaddr = json['lastaddr'];
|
lastaddr = json['lastaddr'];
|
||||||
lastlogon = json['lastlogon'];
|
lastlogon = int.tryParse(json['lastlogon'].toString());
|
||||||
retries = json['retries'];
|
retries = json['retries'];
|
||||||
platform = json['platform'];
|
platform = json['platform'];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:dio_log/dio_log.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -9,6 +10,7 @@ import 'package:qinglong_app/base/userinfo_viewmodel.dart';
|
|||||||
import 'package:qinglong_app/main.dart';
|
import 'package:qinglong_app/main.dart';
|
||||||
import 'package:qinglong_app/module/login/user_bean.dart';
|
import 'package:qinglong_app/module/login/user_bean.dart';
|
||||||
import 'package:qinglong_app/utils/extension.dart';
|
import 'package:qinglong_app/utils/extension.dart';
|
||||||
|
import 'package:qinglong_app/utils/update_utils.dart';
|
||||||
import 'package:qinglong_app/utils/utils.dart';
|
import 'package:qinglong_app/utils/utils.dart';
|
||||||
import 'package:flip_card/flip_card.dart';
|
import 'package:flip_card/flip_card.dart';
|
||||||
|
|
||||||
@@ -22,7 +24,8 @@ class LoginPage extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LoginPageState extends ConsumerState<LoginPage> {
|
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 _userNameController = TextEditingController();
|
||||||
final TextEditingController _passwordController = TextEditingController();
|
final TextEditingController _passwordController = TextEditingController();
|
||||||
final TextEditingController _cIdController = TextEditingController();
|
final TextEditingController _cIdController = TextEditingController();
|
||||||
@@ -38,7 +41,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
useSecretLogin = getIt<UserInfoViewModel>().useSecretLogined;
|
useSecretLogin = getIt<UserInfoViewModel>().useSecretLogined;
|
||||||
|
|
||||||
if (getIt<UserInfoViewModel>().userName != null && getIt<UserInfoViewModel>().userName!.isNotEmpty) {
|
if (getIt<UserInfoViewModel>().userName != null &&
|
||||||
|
getIt<UserInfoViewModel>().userName!.isNotEmpty) {
|
||||||
if (getIt<UserInfoViewModel>().useSecretLogined) {
|
if (getIt<UserInfoViewModel>().useSecretLogined) {
|
||||||
_cIdController.text = getIt<UserInfoViewModel>().userName!;
|
_cIdController.text = getIt<UserInfoViewModel>().userName!;
|
||||||
} else {
|
} else {
|
||||||
@@ -48,7 +52,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
} else {
|
} else {
|
||||||
rememberPassword = false;
|
rememberPassword = false;
|
||||||
}
|
}
|
||||||
if (getIt<UserInfoViewModel>().passWord != null && getIt<UserInfoViewModel>().passWord!.isNotEmpty) {
|
if (getIt<UserInfoViewModel>().passWord != null &&
|
||||||
|
getIt<UserInfoViewModel>().passWord!.isNotEmpty) {
|
||||||
if (getIt<UserInfoViewModel>().useSecretLogined) {
|
if (getIt<UserInfoViewModel>().useSecretLogined) {
|
||||||
_cSecretController.text = getIt<UserInfoViewModel>().passWord!;
|
_cSecretController.text = getIt<UserInfoViewModel>().passWord!;
|
||||||
} else {
|
} else {
|
||||||
@@ -57,6 +62,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
}
|
}
|
||||||
getIt<UserInfoViewModel>().updateToken("");
|
getIt<UserInfoViewModel>().updateToken("");
|
||||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||||
|
update();
|
||||||
if (useSecretLogin) {
|
if (useSecretLogin) {
|
||||||
cardKey.currentState?.toggleCard();
|
cardKey.currentState?.toggleCard();
|
||||||
}
|
}
|
||||||
@@ -107,9 +113,28 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Image.asset(
|
GestureDetector(
|
||||||
"assets/images/ql.png",
|
onDoubleTap: () {
|
||||||
height: 45,
|
if (debugBtnIsShow()) {
|
||||||
|
dismissDebugBtn();
|
||||||
|
} else {
|
||||||
|
showDebugBtn(context,
|
||||||
|
btnColor: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.primaryColor);
|
||||||
|
}
|
||||||
|
WidgetsBinding.instance?.endOfFrame;
|
||||||
|
},
|
||||||
|
child: ColorFiltered(
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
ref.watch(themeProvider).primaryColor,
|
||||||
|
BlendMode.srcIn,
|
||||||
|
),
|
||||||
|
child: Image.asset(
|
||||||
|
"assets/images/ql.png",
|
||||||
|
height: 45,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -136,6 +161,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
),
|
),
|
||||||
FlipCard(
|
FlipCard(
|
||||||
key: cardKey,
|
key: cardKey,
|
||||||
|
flipOnTouch: false,
|
||||||
onFlipDone: (back) {
|
onFlipDone: (back) {
|
||||||
useSecretLogin = back;
|
useSecretLogin = back;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@@ -164,7 +190,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
},
|
},
|
||||||
controller: _userNameController,
|
controller: _userNameController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
contentPadding:
|
||||||
|
EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||||
hintText: "请输入用户名",
|
hintText: "请输入用户名",
|
||||||
),
|
),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
@@ -186,7 +213,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
controller: _passwordController,
|
controller: _passwordController,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
contentPadding:
|
||||||
|
EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||||
hintText: "请输入密码",
|
hintText: "请输入密码",
|
||||||
),
|
),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
@@ -220,7 +248,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
},
|
},
|
||||||
controller: _cIdController,
|
controller: _cIdController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
contentPadding:
|
||||||
|
EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||||
hintText: "请输入client_id",
|
hintText: "请输入client_id",
|
||||||
),
|
),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
@@ -242,7 +271,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
controller: _cSecretController,
|
controller: _cSecretController,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
contentPadding:
|
||||||
|
EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||||
hintText: "请输入client_secret",
|
hintText: "请输入client_secret",
|
||||||
),
|
),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
@@ -280,18 +310,19 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
cardKey.currentState?.toggleCard();
|
cardKey.currentState?.toggleCard();
|
||||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance
|
||||||
|
?.addPostFrameCallback((timeStamp) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
loginByUserName() ? "client_id登录" : "用户名密码登录",
|
loginByUserName() ? "client_id登录" : "账号登录",
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -313,7 +344,12 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 5,
|
vertical: 5,
|
||||||
),
|
),
|
||||||
color: canClickLoginBtn() ? primaryColor : primaryColor.withOpacity(0.4),
|
color: canClickLoginBtn()
|
||||||
|
? ref.watch(themeProvider).primaryColor
|
||||||
|
: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.primaryColor
|
||||||
|
.withOpacity(0.4),
|
||||||
child: isLoading
|
child: isLoading
|
||||||
? const CupertinoActivityIndicator()
|
? const CupertinoActivityIndicator()
|
||||||
: const Text(
|
: const Text(
|
||||||
@@ -325,12 +361,15 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Http.pushedLoginPage = false;
|
Http.pushedLoginPage = false;
|
||||||
Utils.hideKeyBoard(context);
|
Utils.hideKeyBoard(context);
|
||||||
getIt<UserInfoViewModel>().updateHost(_hostController.text);
|
getIt<UserInfoViewModel>()
|
||||||
|
.updateHost(_hostController.text);
|
||||||
Http.clear();
|
Http.clear();
|
||||||
if (loginByUserName()) {
|
if (loginByUserName()) {
|
||||||
login(_userNameController.text, _passwordController.text);
|
login(_userNameController.text,
|
||||||
|
_passwordController.text);
|
||||||
} else {
|
} else {
|
||||||
login(_cIdController.text, _cSecretController.text);
|
login(_cIdController.text,
|
||||||
|
_cSecretController.text);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -367,7 +406,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
loginSuccess(response, userName, password);
|
loginSuccess(response, userName, password);
|
||||||
} else if (loginByUserName() && response.code == 401) {
|
} else if (loginByUserName() && response.code == 401) {
|
||||||
//可能用户使用的是老版本qinglong
|
//可能用户使用的是老版本qinglong
|
||||||
HttpResponse<LoginBean> oldResponse = await Api.loginOld(userName, password);
|
HttpResponse<LoginBean> oldResponse =
|
||||||
|
await Api.loginOld(userName, password);
|
||||||
if (oldResponse.success) {
|
if (oldResponse.success) {
|
||||||
loginSuccess(oldResponse, userName, password);
|
loginSuccess(oldResponse, userName, password);
|
||||||
} else {
|
} else {
|
||||||
@@ -398,11 +438,14 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void loginSuccess(HttpResponse<LoginBean> response, String userName, String password) {
|
void loginSuccess(
|
||||||
|
HttpResponse<LoginBean> response, String userName, String password) {
|
||||||
getIt<UserInfoViewModel>().updateToken(response.bean?.token ?? "");
|
getIt<UserInfoViewModel>().updateToken(response.bean?.token ?? "");
|
||||||
getIt<UserInfoViewModel>().useSecretLogin(!loginByUserName());
|
getIt<UserInfoViewModel>().useSecretLogin(!loginByUserName());
|
||||||
if (rememberPassword) {
|
if (rememberPassword) {
|
||||||
getIt<UserInfoViewModel>().updateUserName(userName, password);
|
getIt<UserInfoViewModel>().updateUserName(userName, password);
|
||||||
|
} else {
|
||||||
|
getIt<UserInfoViewModel>().updateUserName("", "");
|
||||||
}
|
}
|
||||||
Navigator.of(context).pushReplacementNamed(Routes.routeHomePage);
|
Navigator.of(context).pushReplacementNamed(Routes.routeHomePage);
|
||||||
}
|
}
|
||||||
@@ -412,9 +455,11 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
|
|
||||||
if (_hostController.text.isEmpty) return false;
|
if (_hostController.text.isEmpty) return false;
|
||||||
if (!loginByUserName()) {
|
if (!loginByUserName()) {
|
||||||
return _cIdController.text.isNotEmpty && _cSecretController.text.isNotEmpty;
|
return _cIdController.text.isNotEmpty &&
|
||||||
|
_cSecretController.text.isNotEmpty;
|
||||||
} else {
|
} else {
|
||||||
return _userNameController.text.isNotEmpty && _passwordController.text.isNotEmpty;
|
return _userNameController.text.isNotEmpty &&
|
||||||
|
_passwordController.text.isNotEmpty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,12 +505,13 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.of(context).pop(true);
|
Navigator.of(context).pop(true);
|
||||||
HttpResponse<LoginBean> response = await Api.loginTwo(userName, password, twoFact);
|
HttpResponse<LoginBean> response =
|
||||||
|
await Api.loginTwo(userName, password, twoFact);
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
loginSuccess(response, userName, password);
|
loginSuccess(response, userName, password);
|
||||||
} else {
|
} else {
|
||||||
@@ -481,4 +527,15 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
String? result = await UpdateUtils().checkUpdate();
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
UpdateDialog updateDialog = UpdateDialog(context,
|
||||||
|
title: "发现新版本", updateContent: "版本号:v${result}", onUpdate: () {
|
||||||
|
UpdateUtils.launchURL(result);
|
||||||
|
});
|
||||||
|
updateDialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:qinglong_app/base/ql_app_bar.dart';
|
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:qinglong_app/base/theme.dart';
|
import 'package:qinglong_app/base/theme.dart';
|
||||||
|
import 'package:qinglong_app/utils/update_utils.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import '../../main.dart';
|
import '../../main.dart';
|
||||||
@@ -23,6 +24,20 @@ class _AboutPageState extends ConsumerState<AboutPage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
getInfo();
|
getInfo();
|
||||||
|
|
||||||
|
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
String? result = await UpdateUtils().checkUpdate(true);
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
UpdateDialog updateDialog = UpdateDialog(context, title: "发现新版本", updateContent: "版本号:v${result}", onUpdate: () {
|
||||||
|
UpdateUtils.launchURL(result);
|
||||||
|
});
|
||||||
|
updateDialog.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -76,7 +91,7 @@ class _AboutPageState extends ConsumerState<AboutPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"Telegram频道",
|
"Telegram频道",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -92,7 +107,7 @@ class _AboutPageState extends ConsumerState<AboutPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"版本更新",
|
"版本更新",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -107,7 +122,7 @@ class _AboutPageState extends ConsumerState<AboutPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"项目地址",
|
"项目地址",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -37,10 +37,6 @@ class _AddDependencyPageState extends ConsumerState<AddDependencyPage> {
|
|||||||
title: "新增依赖",
|
title: "新增依赖",
|
||||||
actions: [
|
actions: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onLongPress: () {
|
|
||||||
showDebugBtn(context, btnColor: Colors.blue);
|
|
||||||
WidgetsBinding.instance?.endOfFrame;
|
|
||||||
},
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
submit();
|
submit();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ class DependencyBean {
|
|||||||
|
|
||||||
DependencyBean.fromJson(Map<String, dynamic> json) {
|
DependencyBean.fromJson(Map<String, dynamic> json) {
|
||||||
sId = json['_id'];
|
sId = json['_id'];
|
||||||
created = json['created'];
|
created = int.tryParse(json['created'].toString());
|
||||||
status = json['status'];
|
status = json['status'];
|
||||||
type = json['type'];
|
type = json['type'];
|
||||||
timestamp = json['timestamp'];
|
timestamp = json['timestamp'].toString();
|
||||||
name = json['name'];
|
name = json['name'];
|
||||||
log = json['log'].cast<String>();
|
log = json['log'].cast<String>();
|
||||||
remark = json['remark'];
|
remark = json['remark'];
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ class DependencyCell extends ConsumerWidget {
|
|||||||
bean.status == 1
|
bean.status == 1
|
||||||
? Icon(
|
? Icon(
|
||||||
CupertinoIcons.checkmark_circle,
|
CupertinoIcons.checkmark_circle,
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
size: 16,
|
size: 16,
|
||||||
)
|
)
|
||||||
: (bean.status == 2
|
: (bean.status == 2
|
||||||
@@ -348,7 +348,7 @@ class DependencyCell extends ConsumerWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LoginLogBean {
|
|||||||
{this.timestamp, this.address, this.ip, this.platform, this.status});
|
{this.timestamp, this.address, this.ip, this.platform, this.status});
|
||||||
|
|
||||||
LoginLogBean.fromJson(Map<String, dynamic> json) {
|
LoginLogBean.fromJson(Map<String, dynamic> json) {
|
||||||
timestamp = json['timestamp'];
|
timestamp = int.tryParse(json['timestamp'].toString());
|
||||||
address = json['address'];
|
address = json['address'];
|
||||||
ip = json['ip'];
|
ip = json['ip'];
|
||||||
platform = json['platform'];
|
platform = json['platform'];
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class _LoginLogPageState extends ConsumerState<LoginLogPage> with LazyLoadState<
|
|||||||
trailing: item.status == 0
|
trailing: item.status == 0
|
||||||
? Icon(
|
? Icon(
|
||||||
CupertinoIcons.checkmark_circle,
|
CupertinoIcons.checkmark_circle,
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
size: 16,
|
size: 16,
|
||||||
)
|
)
|
||||||
: const Icon(
|
: const Icon(
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
Text(
|
Text(
|
||||||
"脚本管理",
|
"脚本管理",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -92,7 +95,10 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
Text(
|
Text(
|
||||||
"依赖管理",
|
"依赖管理",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -116,16 +122,21 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.only(
|
||||||
vertical: 8,
|
top: 8,
|
||||||
horizontal: 15,
|
bottom: 15,
|
||||||
|
left: 15,
|
||||||
|
right: 15,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"任务日志",
|
"任务日志",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -178,7 +189,10 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
Text(
|
Text(
|
||||||
"登录日志",
|
"登录日志",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -206,9 +220,11 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
},
|
},
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.only(
|
||||||
vertical: 10,
|
top: 8,
|
||||||
horizontal: 15,
|
bottom: 15,
|
||||||
|
left: 15,
|
||||||
|
right: 15,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
@@ -217,7 +233,10 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
Text(
|
Text(
|
||||||
"修改密码",
|
"修改密码",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -261,7 +280,8 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
Text(
|
Text(
|
||||||
"夜间模式",
|
"夜间模式",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color:
|
||||||
|
ref.watch(themeProvider).themeColor.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -278,6 +298,44 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
const Divider(
|
const Divider(
|
||||||
indent: 15,
|
indent: 15,
|
||||||
),
|
),
|
||||||
|
GestureDetector(
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
Routes.routeTheme,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 15,
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"主题设置",
|
||||||
|
style: TextStyle(
|
||||||
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
const Icon(
|
||||||
|
CupertinoIcons.right_chevron,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
indent: 15,
|
||||||
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -299,7 +357,10 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
Text(
|
Text(
|
||||||
"关于",
|
"关于",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -353,12 +414,13 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
getIt<UserInfoViewModel>().updateToken("");
|
getIt<UserInfoViewModel>().updateToken("");
|
||||||
Navigator.of(context).pushReplacementNamed(Routes.routeLogin);
|
Navigator.of(context)
|
||||||
|
.pushReplacementNamed(Routes.routeLogin);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,24 +5,14 @@ import 'package:json_conversion_annotation/json_conversion_annotation.dart';
|
|||||||
class ScriptBean {
|
class ScriptBean {
|
||||||
String? title;
|
String? title;
|
||||||
String? value;
|
String? value;
|
||||||
String? key;
|
|
||||||
double? mtime;
|
|
||||||
bool? disabled;
|
bool? disabled;
|
||||||
List<ScriptChildren>? children;
|
List<ScriptChildren>? children;
|
||||||
|
|
||||||
ScriptBean(
|
ScriptBean({this.title, this.value, this.disabled, this.children});
|
||||||
{this.title,
|
|
||||||
this.value,
|
|
||||||
this.key,
|
|
||||||
this.mtime,
|
|
||||||
this.disabled,
|
|
||||||
this.children});
|
|
||||||
|
|
||||||
ScriptBean.fromJson(Map<String, dynamic> json) {
|
ScriptBean.fromJson(Map<String, dynamic> json) {
|
||||||
title = json['title'];
|
title = json['title'];
|
||||||
value = json['value'];
|
value = json['value'];
|
||||||
key = json['key'];
|
|
||||||
mtime = json['mtime'];
|
|
||||||
disabled = json['disabled'];
|
disabled = json['disabled'];
|
||||||
if (json['children'] != null) {
|
if (json['children'] != null) {
|
||||||
children = <ScriptChildren>[];
|
children = <ScriptChildren>[];
|
||||||
@@ -36,8 +26,6 @@ class ScriptBean {
|
|||||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
data['title'] = this.title;
|
data['title'] = this.title;
|
||||||
data['value'] = this.value;
|
data['value'] = this.value;
|
||||||
data['key'] = this.key;
|
|
||||||
data['mtime'] = this.mtime;
|
|
||||||
data['disabled'] = this.disabled;
|
data['disabled'] = this.disabled;
|
||||||
if (this.children != null) {
|
if (this.children != null) {
|
||||||
data['children'] = this.children!.map((v) => v.toJson()).toList();
|
data['children'] = this.children!.map((v) => v.toJson()).toList();
|
||||||
@@ -53,17 +41,13 @@ class ScriptBean {
|
|||||||
class ScriptChildren {
|
class ScriptChildren {
|
||||||
String? title;
|
String? title;
|
||||||
String? value;
|
String? value;
|
||||||
String? key;
|
|
||||||
double? mtime;
|
|
||||||
String? parent;
|
String? parent;
|
||||||
|
|
||||||
ScriptChildren({this.title, this.value, this.key, this.mtime, this.parent});
|
ScriptChildren({this.title, this.value, this.parent});
|
||||||
|
|
||||||
ScriptChildren.fromJson(Map<String, dynamic> json) {
|
ScriptChildren.fromJson(Map<String, dynamic> json) {
|
||||||
title = json['title'];
|
title = json['title'];
|
||||||
value = json['value'];
|
value = json['value'];
|
||||||
key = json['key'];
|
|
||||||
mtime = json['mtime'];
|
|
||||||
parent = json['parent'];
|
parent = json['parent'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,8 +55,6 @@ class ScriptChildren {
|
|||||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
data['title'] = this.title;
|
data['title'] = this.title;
|
||||||
data['value'] = this.value;
|
data['value'] = this.value;
|
||||||
data['key'] = this.key;
|
|
||||||
data['mtime'] = this.mtime;
|
|
||||||
data['parent'] = this.parent;
|
data['parent'] = this.parent;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class _ScriptDetailPageState extends ConsumerState<ScriptDetailPage> with LazyLo
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|||||||
478
lib/module/others/theme_page.dart
Normal file
478
lib/module/others/theme_page.dart
Normal file
@@ -0,0 +1,478 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||||
|
import 'package:qinglong_app/base/theme.dart';
|
||||||
|
|
||||||
|
class ThemePage extends ConsumerStatefulWidget {
|
||||||
|
const ThemePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ThemePageState createState() => _ThemePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ThemePageState extends ConsumerState<ThemePage> {
|
||||||
|
late Color _primaryColor;
|
||||||
|
List<Color> colors = [];
|
||||||
|
double colorHeight = 40;
|
||||||
|
double smallColorHeight = 8;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_primaryColor = ref.read(themeProvider).primaryColor;
|
||||||
|
colors.add(const Color(0xFF299343));
|
||||||
|
colors.addAll([
|
||||||
|
Colors.red,
|
||||||
|
Colors.pink,
|
||||||
|
Colors.purple,
|
||||||
|
Colors.deepPurple,
|
||||||
|
Colors.indigo,
|
||||||
|
Colors.blue,
|
||||||
|
Colors.lightBlue,
|
||||||
|
Colors.cyan,
|
||||||
|
Colors.teal,
|
||||||
|
Colors.green,
|
||||||
|
Colors.lightGreen,
|
||||||
|
Colors.lime,
|
||||||
|
Colors.yellow,
|
||||||
|
Colors.amber,
|
||||||
|
Colors.orange,
|
||||||
|
Colors.deepOrange,
|
||||||
|
Colors.brown,
|
||||||
|
Colors.blueGrey,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xff999999),
|
||||||
|
appBar: QlAppBar(
|
||||||
|
title: '主题设置',
|
||||||
|
canBack: true,
|
||||||
|
actions: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
submit();
|
||||||
|
},
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 15,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
"保存",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
bottom: true,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(context).size.height * 3 / 4 - kToolbarHeight,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: _primaryColor,
|
||||||
|
title: Text("示例页面"),
|
||||||
|
elevation: 0,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: ListView.builder(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
color: index == 0
|
||||||
|
? ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.pinColor()
|
||||||
|
: Colors.transparent,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 15,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Random().nextBool()
|
||||||
|
? const SizedBox.shrink()
|
||||||
|
: SizedBox(
|
||||||
|
width: 15,
|
||||||
|
height: 15,
|
||||||
|
child:
|
||||||
|
CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
color: _primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: Random().nextBool()
|
||||||
|
? 0
|
||||||
|
: 5,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Text(
|
||||||
|
"示例名称",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow:
|
||||||
|
TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
overflow: TextOverflow
|
||||||
|
.ellipsis,
|
||||||
|
color: ref
|
||||||
|
.watch(
|
||||||
|
themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Text(
|
||||||
|
"上午10:00",
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.descColor(),
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Random().nextBool()
|
||||||
|
? const Icon(
|
||||||
|
Icons.dnd_forwardslash,
|
||||||
|
size: 12,
|
||||||
|
color: Colors.red,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
const SizedBox(
|
||||||
|
width: 5,
|
||||||
|
),
|
||||||
|
Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Text(
|
||||||
|
"10 1-12/2 * * *",
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.descColor(),
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Text(
|
||||||
|
"task raw post.js",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.descColor(),
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
height: 1,
|
||||||
|
indent: 15,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: 100,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 15,
|
||||||
|
),
|
||||||
|
height: colorHeight + 20,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: ListView.separated(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 15,
|
||||||
|
),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == 0) {
|
||||||
|
return GestureDetector(
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTap: () {
|
||||||
|
pickColor();
|
||||||
|
},
|
||||||
|
child: SizedBox(
|
||||||
|
width: colorHeight,
|
||||||
|
height: colorHeight,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[0],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
left: 0,
|
||||||
|
top: colorHeight / 4 - smallColorHeight / 2,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[1],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
left: 0,
|
||||||
|
bottom: colorHeight / 4 - smallColorHeight / 2,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[2],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
left: colorHeight / 2 - smallColorHeight / 2,
|
||||||
|
top: 0,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[3],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
right: 0,
|
||||||
|
top: colorHeight / 4 - smallColorHeight / 2,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[4],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
right: 0,
|
||||||
|
bottom: colorHeight / 4 - smallColorHeight / 2,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[5],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
left: colorHeight / 2 - smallColorHeight / 2,
|
||||||
|
bottom: 0,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[6],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
left: colorHeight / 2 - smallColorHeight / 2,
|
||||||
|
bottom: 0,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
child: Container(
|
||||||
|
width: smallColorHeight,
|
||||||
|
height: smallColorHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[7],
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(smallColorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
left: colorHeight / 2 - smallColorHeight / 2,
|
||||||
|
bottom: colorHeight / 2 - smallColorHeight / 2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
index = index - 1;
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
_primaryColor = colors[index];
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: SizedBox(
|
||||||
|
width: colorHeight,
|
||||||
|
height: colorHeight,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors[index],
|
||||||
|
borderRadius: BorderRadius.circular(colorHeight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemCount: colors.length + 1,
|
||||||
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
|
return const SizedBox(
|
||||||
|
width: 15,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pickColor() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
titlePadding: const EdgeInsets.all(0),
|
||||||
|
contentPadding: const EdgeInsets.all(0),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: ColorPicker(
|
||||||
|
pickerColor: _primaryColor,
|
||||||
|
onColorChanged: (color) {
|
||||||
|
_primaryColor = color;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
colorPickerWidth: 300,
|
||||||
|
pickerAreaHeightPercent: 0.7,
|
||||||
|
enableAlpha: false,
|
||||||
|
pickerAreaBorderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(2),
|
||||||
|
topRight: Radius.circular(2),
|
||||||
|
),
|
||||||
|
hexInputBar: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void submit() {
|
||||||
|
ref.read(themeProvider).changePrimaryColor(_primaryColor);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,14 +44,14 @@ class TaskBean {
|
|||||||
schedule = json['schedule'].toString();
|
schedule = json['schedule'].toString();
|
||||||
saved = json['saved'];
|
saved = json['saved'];
|
||||||
sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : "");
|
sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : "");
|
||||||
created = json['created'];
|
created = int.tryParse(json['created'].toString());
|
||||||
status = json['status'];
|
status = json['status'];
|
||||||
timestamp = json['timestamp'].toString();
|
timestamp = json['timestamp'].toString();
|
||||||
isSystem = json['isSystem'];
|
isSystem = json['isSystem'];
|
||||||
isDisabled = json['isDisabled'];
|
isDisabled = json['isDisabled'];
|
||||||
logPath = json['log_path'].toString();
|
logPath = json['log_path'].toString();
|
||||||
isPinned = json['isPinned'];
|
isPinned = json['isPinned'];
|
||||||
lastExecutionTime = json['last_execution_time'];
|
lastExecutionTime = int.tryParse(json['last_execution_time'].toString());
|
||||||
lastRunningTime = json['last_running_time'];
|
lastRunningTime = json['last_running_time'];
|
||||||
pid = json['pid'].toString();
|
pid = json['pid'].toString();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ class _TaskDetailPageState extends ConsumerState<TaskDetailPage> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|||||||
@@ -102,9 +102,17 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
TaskBean item = list[index];
|
TaskBean item = list[index];
|
||||||
|
|
||||||
if (_searchController.text.isEmpty ||
|
if (_searchController.text.isEmpty ||
|
||||||
(item.name?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false) ||
|
(item.name
|
||||||
(item.command?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false) ||
|
?.toLowerCase()
|
||||||
(item.schedule?.contains(_searchController.text.toLowerCase()) ?? false)) {
|
.contains(_searchController.text.toLowerCase()) ??
|
||||||
|
false) ||
|
||||||
|
(item.command
|
||||||
|
?.toLowerCase()
|
||||||
|
.contains(_searchController.text.toLowerCase()) ??
|
||||||
|
false) ||
|
||||||
|
(item.schedule
|
||||||
|
?.contains(_searchController.text.toLowerCase()) ??
|
||||||
|
false)) {
|
||||||
return TaskItemCell(item, ref);
|
return TaskItemCell(item, ref);
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
@@ -175,10 +183,16 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
bean.status! == 1 ? "运行" : "停止运行",
|
bean.status! == 1 ? "运行" : "停止运行",
|
||||||
),
|
),
|
||||||
trailingIcon: bean.status! == 1 ? CupertinoIcons.memories : CupertinoIcons.stop_circle,
|
trailingIcon: bean.status! == 1
|
||||||
|
? CupertinoIcons.memories
|
||||||
|
: CupertinoIcons.stop_circle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
startCron(context, ref);
|
if (bean.status! == 1) {
|
||||||
|
startCron(context, ref);
|
||||||
|
} else {
|
||||||
|
stopCron(context, ref);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
QLCupertinoContextMenuAction(
|
QLCupertinoContextMenuAction(
|
||||||
@@ -193,7 +207,8 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
child: const Text("编辑"),
|
child: const Text("编辑"),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pushNamed(Routes.routeAddTask, arguments: bean);
|
Navigator.of(context)
|
||||||
|
.pushNamed(Routes.routeAddTask, arguments: bean);
|
||||||
},
|
},
|
||||||
trailingIcon: CupertinoIcons.pencil_outline,
|
trailingIcon: CupertinoIcons.pencil_outline,
|
||||||
),
|
),
|
||||||
@@ -203,7 +218,9 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
pinTask();
|
pinTask();
|
||||||
},
|
},
|
||||||
trailingIcon: bean.isPinned! == 0 ? CupertinoIcons.pin : CupertinoIcons.pin_slash,
|
trailingIcon: bean.isPinned! == 0
|
||||||
|
? CupertinoIcons.pin
|
||||||
|
: CupertinoIcons.pin_slash,
|
||||||
),
|
),
|
||||||
QLCupertinoContextMenuAction(
|
QLCupertinoContextMenuAction(
|
||||||
child: Text(bean.isDisabled! == 0 ? "禁用" : "启用"),
|
child: Text(bean.isDisabled! == 0 ? "禁用" : "启用"),
|
||||||
@@ -212,7 +229,9 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
enableTask();
|
enableTask();
|
||||||
},
|
},
|
||||||
isDestructiveAction: true,
|
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(
|
QLCupertinoContextMenuAction(
|
||||||
child: const Text("删除"),
|
child: const Text("删除"),
|
||||||
@@ -229,15 +248,17 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
child: Container(
|
child: Container(
|
||||||
color: isDark ? const Color(0xff333333) : Theme.of(context).scaffoldBackgroundColor,
|
color: isDark
|
||||||
|
? const Color(0xff333333)
|
||||||
|
: Theme.of(context).scaffoldBackgroundColor,
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 5,
|
left: 5,
|
||||||
right: 5,
|
right: 5,
|
||||||
top: 5,
|
top: 5,
|
||||||
bottom: isDark ? 5 : 20,
|
bottom: isDark ? 5 : 20,
|
||||||
),
|
),
|
||||||
child: ClipRRect(
|
child: SizedBox(
|
||||||
borderRadius: BorderRadius.circular(15),
|
height: 200,
|
||||||
child: TaskDetailPage(
|
child: TaskDetailPage(
|
||||||
bean,
|
bean,
|
||||||
hideAppbar: true,
|
hideAppbar: true,
|
||||||
@@ -252,7 +273,9 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
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(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 15,
|
horizontal: 15,
|
||||||
vertical: 8,
|
vertical: 8,
|
||||||
@@ -265,39 +288,59 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Material(
|
Expanded(
|
||||||
color: Colors.transparent,
|
child: Row(
|
||||||
child: Text(
|
mainAxisSize: MainAxisSize.max,
|
||||||
bean.name ?? "",
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
maxLines: 1,
|
children: [
|
||||||
style: TextStyle(
|
bean.status == 1
|
||||||
overflow: TextOverflow.ellipsis,
|
? const SizedBox.shrink()
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
: SizedBox(
|
||||||
fontSize: 18,
|
width: 15,
|
||||||
),
|
height: 15,
|
||||||
),
|
child: CircularProgressIndicator(
|
||||||
),
|
strokeWidth: 2,
|
||||||
const SizedBox(
|
color:
|
||||||
width: 5,
|
ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
bean.status == 1
|
),
|
||||||
? const SizedBox.shrink()
|
SizedBox(
|
||||||
: const SizedBox(
|
width: bean.status == 1 ? 0 : 5,
|
||||||
width: 15,
|
),
|
||||||
height: 15,
|
Expanded(
|
||||||
child: CircularProgressIndicator(
|
child: Material(
|
||||||
strokeWidth: 2,
|
color: Colors.transparent,
|
||||||
|
child: Text(
|
||||||
|
bean.name ?? "",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: ref
|
||||||
|
.watch(themeProvider)
|
||||||
|
.themeColor
|
||||||
|
.titleColor(),
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
Material(
|
Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Text(
|
child: Text(
|
||||||
(bean.lastExecutionTime == null || bean.lastExecutionTime == 0) ? "-" : Utils.formatMessageTime(bean.lastExecutionTime!),
|
(bean.lastExecutionTime == null ||
|
||||||
|
bean.lastExecutionTime == 0)
|
||||||
|
? "-"
|
||||||
|
: Utils.formatMessageTime(
|
||||||
|
bean.lastExecutionTime!),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
color:
|
||||||
|
ref.watch(themeProvider).themeColor.descColor(),
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -310,21 +353,6 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
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
|
bean.isDisabled == 1
|
||||||
? const Icon(
|
? const Icon(
|
||||||
Icons.dnd_forwardslash,
|
Icons.dnd_forwardslash,
|
||||||
@@ -332,6 +360,22 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
|
const SizedBox(
|
||||||
|
width: 5,
|
||||||
|
),
|
||||||
|
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(
|
const SizedBox(
|
||||||
@@ -433,7 +477,7 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
"确定",
|
"确定",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: primaryColor,
|
color: ref.watch(themeProvider).primaryColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class TaskViewModel extends BaseViewModel {
|
|||||||
HttpResponse<NullResponse> result = await Api.startTasks([cron]);
|
HttpResponse<NullResponse> result = await Api.startTasks([cron]);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
list.firstWhere((element) => element.sId == cron).status = 0;
|
list.firstWhere((element) => element.sId == cron).status = 0;
|
||||||
|
sortList();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
failToast(result.message, notify: true);
|
failToast(result.message, notify: true);
|
||||||
@@ -58,6 +59,7 @@ class TaskViewModel extends BaseViewModel {
|
|||||||
HttpResponse<NullResponse> result = await Api.stopTasks([cron]);
|
HttpResponse<NullResponse> result = await Api.stopTasks([cron]);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
list.firstWhere((element) => element.sId == cron).status = 1;
|
list.firstWhere((element) => element.sId == cron).status = 1;
|
||||||
|
sortList();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
failToast(result.message, notify: true);
|
failToast(result.message, notify: true);
|
||||||
|
|||||||
395
lib/utils/update_utils.dart
Normal file
395
lib/utils/update_utils.dart
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
import 'package:qinglong_app/base/http/url.dart';
|
||||||
|
import 'package:qinglong_app/utils/extension.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
/// @author NewTab
|
||||||
|
|
||||||
|
class UpdateUtils {
|
||||||
|
Future<String?> checkUpdate([bool remind = false]) async {
|
||||||
|
try {
|
||||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
|
String version = packageInfo.version;
|
||||||
|
String url = Url.checkUpdateUrl;
|
||||||
|
Dio dio = Dio(BaseOptions(
|
||||||
|
connectTimeout: 50000,
|
||||||
|
receiveTimeout: 50000,
|
||||||
|
sendTimeout: 50000,
|
||||||
|
));
|
||||||
|
var response = await dio.get(url);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
if (version == response.data as String) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return response.data as String;
|
||||||
|
}
|
||||||
|
} on DioError catch (e) {
|
||||||
|
if (remind) {
|
||||||
|
"无法连接到github服务器,版本更新检测失败".toast();
|
||||||
|
}
|
||||||
|
logger.e(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void launchURL(String version) async {
|
||||||
|
try {
|
||||||
|
await launch("https://github.com/qinglong-app/qinglong_app/releases/download/v$version/app-release-v$version.apk");
|
||||||
|
} catch (e) {
|
||||||
|
logger.e(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///版本更新加提示框
|
||||||
|
class UpdateDialog {
|
||||||
|
bool _isShowing = false;
|
||||||
|
late BuildContext _context;
|
||||||
|
late UpdateWidget _widget;
|
||||||
|
|
||||||
|
UpdateDialog(BuildContext context,
|
||||||
|
{double width = 0.0,
|
||||||
|
required String title,
|
||||||
|
required String updateContent,
|
||||||
|
required VoidCallback onUpdate,
|
||||||
|
double titleTextSize = 16.0,
|
||||||
|
double contentTextSize = 14.0,
|
||||||
|
double buttonTextSize = 14.0,
|
||||||
|
double progress = -1.0,
|
||||||
|
Color progressBackgroundColor = const Color(0xFFFFCDD2),
|
||||||
|
Image? topImage,
|
||||||
|
double extraHeight = 5.0,
|
||||||
|
double radius = 4.0,
|
||||||
|
Color themeColor = Colors.red,
|
||||||
|
bool enableIgnore = false,
|
||||||
|
VoidCallback? onIgnore,
|
||||||
|
bool isForce = false,
|
||||||
|
String? updateButtonText,
|
||||||
|
String? ignoreButtonText,
|
||||||
|
VoidCallback? onClose}) {
|
||||||
|
_context = context;
|
||||||
|
_widget = UpdateWidget(
|
||||||
|
width: width,
|
||||||
|
title: title,
|
||||||
|
updateContent: updateContent,
|
||||||
|
onUpdate: onUpdate,
|
||||||
|
titleTextSize: titleTextSize,
|
||||||
|
contentTextSize: contentTextSize,
|
||||||
|
buttonTextSize: buttonTextSize,
|
||||||
|
progress: progress,
|
||||||
|
topImage: topImage,
|
||||||
|
extraHeight: extraHeight,
|
||||||
|
radius: radius,
|
||||||
|
themeColor: themeColor,
|
||||||
|
progressBackgroundColor: progressBackgroundColor,
|
||||||
|
enableIgnore: enableIgnore,
|
||||||
|
onIgnore: onIgnore,
|
||||||
|
isForce: isForce,
|
||||||
|
updateButtonText: updateButtonText ?? '更新',
|
||||||
|
ignoreButtonText: ignoreButtonText ?? '忽略此版本',
|
||||||
|
onClose: onClose ?? () => dismiss());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 显示弹窗
|
||||||
|
Future<bool> show() {
|
||||||
|
try {
|
||||||
|
if (isShowing()) {
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
showDialog<bool>(
|
||||||
|
context: _context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return WillPopScope(onWillPop: () => Future<bool>.value(false), child: _widget);
|
||||||
|
});
|
||||||
|
_isShowing = true;
|
||||||
|
return Future<bool>.value(true);
|
||||||
|
} catch (err) {
|
||||||
|
_isShowing = false;
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 隐藏弹窗
|
||||||
|
Future<bool> dismiss() {
|
||||||
|
try {
|
||||||
|
if (_isShowing) {
|
||||||
|
_isShowing = false;
|
||||||
|
Navigator.pop(_context);
|
||||||
|
return Future<bool>.value(true);
|
||||||
|
} else {
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 是否显示
|
||||||
|
bool isShowing() {
|
||||||
|
return _isShowing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 更新进度
|
||||||
|
void update(double progress) {
|
||||||
|
if (isShowing()) {
|
||||||
|
_widget.update(progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 显示版本更新提示框
|
||||||
|
static UpdateDialog showUpdate(BuildContext context,
|
||||||
|
{double width = 0.0,
|
||||||
|
required String title,
|
||||||
|
required String updateContent,
|
||||||
|
required VoidCallback onUpdate,
|
||||||
|
double titleTextSize = 16.0,
|
||||||
|
double contentTextSize = 14.0,
|
||||||
|
double buttonTextSize = 14.0,
|
||||||
|
double progress = -1.0,
|
||||||
|
Color progressBackgroundColor = const Color(0xFFFFCDD2),
|
||||||
|
Image? topImage,
|
||||||
|
double extraHeight = 5.0,
|
||||||
|
double radius = 4.0,
|
||||||
|
Color themeColor = Colors.red,
|
||||||
|
bool enableIgnore = false,
|
||||||
|
VoidCallback? onIgnore,
|
||||||
|
String? updateButtonText,
|
||||||
|
String? ignoreButtonText,
|
||||||
|
bool isForce = false}) {
|
||||||
|
final UpdateDialog dialog = UpdateDialog(context,
|
||||||
|
width: width,
|
||||||
|
title: title,
|
||||||
|
updateContent: updateContent,
|
||||||
|
onUpdate: onUpdate,
|
||||||
|
titleTextSize: titleTextSize,
|
||||||
|
contentTextSize: contentTextSize,
|
||||||
|
buttonTextSize: buttonTextSize,
|
||||||
|
progress: progress,
|
||||||
|
topImage: topImage,
|
||||||
|
extraHeight: extraHeight,
|
||||||
|
radius: radius,
|
||||||
|
themeColor: themeColor,
|
||||||
|
progressBackgroundColor: progressBackgroundColor,
|
||||||
|
enableIgnore: enableIgnore,
|
||||||
|
isForce: isForce,
|
||||||
|
updateButtonText: updateButtonText,
|
||||||
|
ignoreButtonText: ignoreButtonText,
|
||||||
|
onIgnore: onIgnore);
|
||||||
|
dialog.show();
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class UpdateWidget extends StatefulWidget {
|
||||||
|
/// 对话框的宽度
|
||||||
|
final double width;
|
||||||
|
|
||||||
|
/// 升级标题
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
/// 更新内容
|
||||||
|
final String updateContent;
|
||||||
|
|
||||||
|
/// 标题文字的大小
|
||||||
|
final double titleTextSize;
|
||||||
|
|
||||||
|
/// 更新文字内容的大小
|
||||||
|
final double contentTextSize;
|
||||||
|
|
||||||
|
/// 按钮文字的大小
|
||||||
|
final double buttonTextSize;
|
||||||
|
|
||||||
|
/// 顶部图片
|
||||||
|
final Widget? topImage;
|
||||||
|
|
||||||
|
/// 拓展高度(适配顶部图片高度不一致的情况)
|
||||||
|
final double extraHeight;
|
||||||
|
|
||||||
|
/// 边框圆角大小
|
||||||
|
final double radius;
|
||||||
|
|
||||||
|
/// 主题颜色
|
||||||
|
final Color themeColor;
|
||||||
|
|
||||||
|
/// 更新事件
|
||||||
|
final VoidCallback onUpdate;
|
||||||
|
|
||||||
|
/// 可忽略更新
|
||||||
|
final bool enableIgnore;
|
||||||
|
|
||||||
|
/// 更新事件
|
||||||
|
final VoidCallback? onIgnore;
|
||||||
|
|
||||||
|
double progress;
|
||||||
|
|
||||||
|
/// 进度条的背景颜色
|
||||||
|
final Color progressBackgroundColor;
|
||||||
|
|
||||||
|
/// 更新事件
|
||||||
|
final VoidCallback? onClose;
|
||||||
|
|
||||||
|
/// 是否是强制更新
|
||||||
|
final bool isForce;
|
||||||
|
|
||||||
|
/// 更新按钮内容
|
||||||
|
final String updateButtonText;
|
||||||
|
|
||||||
|
/// 忽略按钮内容
|
||||||
|
final String ignoreButtonText;
|
||||||
|
|
||||||
|
UpdateWidget(
|
||||||
|
{Key? key,
|
||||||
|
this.width = 0.0,
|
||||||
|
required this.title,
|
||||||
|
required this.updateContent,
|
||||||
|
required this.onUpdate,
|
||||||
|
this.titleTextSize = 16.0,
|
||||||
|
this.contentTextSize = 14.0,
|
||||||
|
this.buttonTextSize = 14.0,
|
||||||
|
this.progress = -1.0,
|
||||||
|
this.progressBackgroundColor = const Color(0xFFFFCDD2),
|
||||||
|
this.topImage,
|
||||||
|
this.extraHeight = 5.0,
|
||||||
|
this.radius = 4.0,
|
||||||
|
this.themeColor = Colors.red,
|
||||||
|
this.enableIgnore = false,
|
||||||
|
this.onIgnore,
|
||||||
|
this.isForce = false,
|
||||||
|
this.updateButtonText = '更新',
|
||||||
|
this.ignoreButtonText = '忽略此版本',
|
||||||
|
this.onClose})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
final _UpdateWidgetState _state = _UpdateWidgetState();
|
||||||
|
|
||||||
|
void update(double progress) {
|
||||||
|
_state.update(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_UpdateWidgetState createState() => _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UpdateWidgetState extends State<UpdateWidget> {
|
||||||
|
void update(double progress) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
widget.progress = progress;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final double dialogWidth = widget.width <= 0 ? getFitWidth(context) * 0.618 : widget.width;
|
||||||
|
return Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: SizedBox(
|
||||||
|
width: dialogWidth,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
width: dialogWidth,
|
||||||
|
child: widget.topImage ?? Image.asset('assets/images/update_bg_app_top.png', fit: BoxFit.fill),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: dialogWidth,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
|
||||||
|
decoration: ShapeDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(widget.radius), bottomRight: Radius.circular(widget.radius)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(top: widget.extraHeight),
|
||||||
|
child: Text(widget.title, style: TextStyle(fontSize: widget.titleTextSize, color: Colors.black)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
child: Text(widget.updateContent, style: TextStyle(fontSize: widget.contentTextSize, color: const Color(0xFF666666))),
|
||||||
|
),
|
||||||
|
Column(children: <Widget>[
|
||||||
|
FractionallySizedBox(
|
||||||
|
widthFactor: 1,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
textStyle: MaterialStateProperty.all(TextStyle(fontSize: widget.buttonTextSize)),
|
||||||
|
foregroundColor: MaterialStateProperty.all(Colors.white),
|
||||||
|
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
||||||
|
elevation: MaterialStateProperty.all(0),
|
||||||
|
backgroundColor: MaterialStateProperty.all(widget.themeColor),
|
||||||
|
),
|
||||||
|
child: Text(widget.updateButtonText),
|
||||||
|
onPressed: widget.onUpdate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.enableIgnore && widget.onIgnore != null)
|
||||||
|
FractionallySizedBox(
|
||||||
|
widthFactor: 1,
|
||||||
|
child: TextButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
textStyle: MaterialStateProperty.all(TextStyle(fontSize: widget.buttonTextSize)),
|
||||||
|
foregroundColor: MaterialStateProperty.all(const Color(0xFF666666)),
|
||||||
|
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
||||||
|
),
|
||||||
|
child: Text(widget.ignoreButtonText),
|
||||||
|
onPressed: widget.onIgnore,
|
||||||
|
))
|
||||||
|
else
|
||||||
|
const SizedBox()
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
if (!widget.isForce)
|
||||||
|
Column(children: <Widget>[
|
||||||
|
const SizedBox(width: 1.5, height: 50, child: DecoratedBox(decoration: BoxDecoration(color: Colors.white))),
|
||||||
|
IconButton(
|
||||||
|
iconSize: 30,
|
||||||
|
constraints: const BoxConstraints(maxHeight: 30, maxWidth: 30),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Image.asset(
|
||||||
|
'assets/images/update_ic_close.png',
|
||||||
|
),
|
||||||
|
onPressed: widget.onClose,
|
||||||
|
)
|
||||||
|
])
|
||||||
|
else
|
||||||
|
const SizedBox()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getFitWidth(BuildContext context) {
|
||||||
|
return min(getScreenHeight(context), getScreenWidth(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getScreenHeight(BuildContext context) {
|
||||||
|
return MediaQuery.of(context).size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getScreenWidth(BuildContext context) {
|
||||||
|
return MediaQuery.of(context).size.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
255
pubspec.lock
255
pubspec.lock
@@ -5,245 +5,245 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "22.0.0"
|
version: "22.0.0"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.2"
|
version: "1.7.2"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.8"
|
version: "3.1.9"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.2"
|
version: "2.8.2"
|
||||||
back_button_interceptor:
|
back_button_interceptor:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: back_button_interceptor
|
name: back_button_interceptor
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.2"
|
version: "5.0.2"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
build:
|
build:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build
|
name: build
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
build_config:
|
build_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_config
|
name: build_config
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
build_daemon:
|
build_daemon:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_resolvers
|
name: build_resolvers
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.0.4"
|
||||||
build_runner:
|
build_runner:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.7"
|
version: "2.1.7"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.3"
|
version: "7.2.3"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_collection
|
name: built_collection
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.1"
|
version: "5.1.1"
|
||||||
built_value:
|
built_value:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.4"
|
version: "8.1.4"
|
||||||
change_app_package_name:
|
change_app_package_name:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: change_app_package_name
|
name: change_app_package_name
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.3"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.1"
|
||||||
checked_yaml:
|
checked_yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: checked_yaml
|
name: checked_yaml
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
cli_util:
|
cli_util:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cli_util
|
name: cli_util
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.5"
|
version: "0.3.5"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
code_builder:
|
code_builder:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: code_builder
|
name: code_builder
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.1.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.15.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: dio
|
name: dio
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.4"
|
version: "4.0.4"
|
||||||
dio_log:
|
dio_log:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: dio_log
|
name: dio_log
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
drag_and_drop_lists:
|
drag_and_drop_lists:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: drag_and_drop_lists
|
name: drag_and_drop_lists
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.2+2"
|
version: "0.3.2+2"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.2"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
flip_card:
|
flip_card:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flip_card
|
name: flip_card
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.0"
|
version: "0.6.0"
|
||||||
flutter:
|
flutter:
|
||||||
@@ -255,49 +255,56 @@ packages:
|
|||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_app_name
|
name: flutter_app_name
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.1"
|
version: "0.1.1"
|
||||||
|
flutter_colorpicker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_colorpicker
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
flutter_highlight:
|
flutter_highlight:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_highlight
|
name: flutter_highlight
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.0"
|
version: "0.7.0"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.2"
|
version: "0.9.2"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_native_splash
|
name: flutter_native_splash
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.3"
|
||||||
flutter_riverpod:
|
flutter_riverpod:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_riverpod
|
name: flutter_riverpod
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
flutter_slidable:
|
flutter_slidable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_slidable
|
name: flutter_slidable
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -314,371 +321,371 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.8"
|
version: "8.0.8"
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: frontend_server_client
|
name: frontend_server_client
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
get_it:
|
get_it:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: get_it
|
name: get_it
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.0"
|
version: "7.2.0"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: glob
|
name: glob
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
highlight:
|
highlight:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: highlight
|
name: highlight
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.0"
|
version: "0.7.0"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.4"
|
version: "0.13.4"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_multi_server
|
name: http_multi_server
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image
|
name: image
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.1"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.0"
|
version: "0.17.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: io
|
name: io
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.3"
|
version: "0.6.3"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.4.0"
|
version: "4.4.0"
|
||||||
json_conversion:
|
json_conversion:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: json_conversion
|
name: json_conversion
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.4"
|
version: "0.0.4"
|
||||||
json_conversion_annotation:
|
json_conversion_annotation:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: json_conversion_annotation
|
name: json_conversion_annotation
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.4"
|
version: "0.0.4"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
logger:
|
logger:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: logger
|
name: logger
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.11"
|
version: "0.12.11"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.7.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
move_to_background:
|
move_to_background:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: move_to_background
|
name: move_to_background
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_config
|
name: package_config
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: package_info_plus
|
name: package_info_plus
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
package_info_plus_linux:
|
package_info_plus_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_linux
|
name: package_info_plus_linux
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
package_info_plus_macos:
|
package_info_plus_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_macos
|
name: package_info_plus_macos
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
package_info_plus_platform_interface:
|
package_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_platform_interface
|
name: package_info_plus_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
package_info_plus_web:
|
package_info_plus_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_web
|
name: package_info_plus_web
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
package_info_plus_windows:
|
package_info_plus_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_windows
|
name: package_info_plus_windows
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.8.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.5"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.5"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.11.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.4.0"
|
version: "4.4.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pool
|
name: pool
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "1.5.0"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.4"
|
version: "4.2.4"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pub_semver
|
name: pub_semver
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
pubspec_parse:
|
pubspec_parse:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
riverpod:
|
riverpod:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: riverpod
|
name: riverpod
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.12"
|
version: "2.0.12"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.10"
|
version: "2.0.10"
|
||||||
shared_preferences_ios:
|
shared_preferences_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_ios
|
name: shared_preferences_ios
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.9"
|
version: "2.0.9"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_linux
|
name: shared_preferences_linux
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.0.4"
|
||||||
shared_preferences_macos:
|
shared_preferences_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_macos
|
name: shared_preferences_macos
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
shared_preferences_platform_interface:
|
shared_preferences_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_platform_interface
|
name: shared_preferences_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
shared_preferences_web:
|
shared_preferences_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.0.4"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
@@ -690,196 +697,196 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_gen
|
name: source_gen
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.10.0"
|
||||||
state_notifier:
|
state_notifier:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: state_notifier
|
name: state_notifier
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.2+1"
|
version: "0.7.2+1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
stream_transform:
|
stream_transform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_transform
|
name: stream_transform
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: synchronized
|
name: synchronized
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.3"
|
version: "0.4.3"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: timing
|
name: timing
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
universal_io:
|
universal_io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: universal_io
|
name: universal_io
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.0.4"
|
||||||
url_launcher:
|
url_launcher:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.18"
|
version: "6.0.18"
|
||||||
url_launcher_android:
|
url_launcher_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.14"
|
version: "6.0.14"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_ios
|
name: url_launcher_ios
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.14"
|
version: "6.0.14"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_linux
|
name: url_launcher_linux
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_macos
|
name: url_launcher_macos
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_platform_interface
|
name: url_launcher_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.5"
|
||||||
url_launcher_web:
|
url_launcher_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6"
|
version: "2.0.6"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_windows
|
name: url_launcher_windows
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: watcher
|
name: watcher
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.6"
|
version: "2.3.6"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.3.1"
|
version: "5.3.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: qinglong_app
|
name: qinglong_app
|
||||||
description: A new Flutter project.
|
description: A new Flutter project.
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
version: 1.0.3+4
|
version: 1.0.4+5
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.15.1 <3.0.0"
|
sdk: ">=2.15.1 <3.0.0"
|
||||||
@@ -31,6 +31,7 @@ dependencies:
|
|||||||
flip_card: ^0.6.0
|
flip_card: ^0.6.0
|
||||||
package_info_plus: ^1.3.0
|
package_info_plus: ^1.3.0
|
||||||
url_launcher: ^6.0.18
|
url_launcher: ^6.0.18
|
||||||
|
flutter_colorpicker: ^1.0.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_native_splash: ^1.3.3
|
flutter_native_splash: ^1.3.3
|
||||||
|
|||||||
@@ -6,8 +6,5 @@
|
|||||||
// tree, read text, and verify that the values of widget properties are correct.
|
// tree, read text, and verify that the values of widget properties are correct.
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
String time = "Wed Jan 12 2022 20:33:39 GMT+0800 (中国标准时间)";
|
|
||||||
|
|
||||||
var result = DateTime.tryParse(time);
|
|
||||||
print(result);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user