mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
优化使用体验
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -44,3 +44,4 @@ app.*.map.json
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
.fvm/
|
||||
@@ -29,7 +29,7 @@ class _BaseStateWidgetState<T extends BaseViewModel> extends ConsumerState<BaseS
|
||||
Widget build(BuildContext context) {
|
||||
var viewModel = ref.watch<T>(widget.model);
|
||||
if (viewModel.failedToast != null) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
(viewModel.failedToast ?? "").toast();
|
||||
viewModel.clearToast();
|
||||
});
|
||||
@@ -72,7 +72,7 @@ class _BaseStateWidgetState<T extends BaseViewModel> extends ConsumerState<BaseS
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
if (widget.onReady != null && !widget.lazyLoad) {
|
||||
widget.onReady!(ref.read<T>(widget.model));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class ThemeViewModel extends ChangeNotifier {
|
||||
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;
|
||||
changeThemeReal(_isInDarkMode, false);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ mixin LazyLoadState<T extends StatefulWidget> on State<T> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
var route = ModalRoute.of(context);
|
||||
void handler(status) {
|
||||
if (status == AnimationStatus.completed) {
|
||||
|
||||
@@ -62,7 +62,7 @@ class QlAppState extends ConsumerState<QlApp> {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
child: MediaQuery(
|
||||
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window).copyWith(
|
||||
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window).copyWith(
|
||||
textScaleFactor: 1,
|
||||
),
|
||||
child: MaterialApp(
|
||||
|
||||
@@ -33,7 +33,7 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
|
||||
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
focusNode.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ class _CodeWidgetState extends State<CodeWidget>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return SelectableText.rich(
|
||||
TextSpan(
|
||||
style: GoogleFonts.droidSansMono(fontSize: 14).apply(
|
||||
|
||||
2
lib/module/env/add_env_page.dart
vendored
2
lib/module/env/add_env_page.dart
vendored
@@ -35,7 +35,7 @@ class _AddEnvPageState extends ConsumerState<AddEnvPage> {
|
||||
} else {
|
||||
envBean = EnvBean();
|
||||
}
|
||||
WidgetsBinding.instance?.addPostFrameCallback(
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(timeStamp) {
|
||||
focusNode.requestFocus();
|
||||
},
|
||||
|
||||
@@ -44,7 +44,7 @@ class _HomePageState extends ConsumerState<HomePage>
|
||||
initTitles();
|
||||
_title = titles[0].title;
|
||||
super.initState();
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
getSystemBean();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:dio_log/dio_log.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_animator/flutter_animator.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:qinglong_app/base/http/http.dart';
|
||||
import 'package:qinglong_app/base/routes.dart';
|
||||
@@ -62,13 +63,15 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
}
|
||||
}
|
||||
getIt<UserInfoViewModel>().updateToken("");
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
if (useSecretLogin) {
|
||||
cardKey.currentState?.toggleCard();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GlobalKey<AnimatorWidgetState> loginKey = GlobalKey<AnimatorWidgetState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -76,273 +79,393 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
value: ref.watch(themeProvider).darkMode == true ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark,
|
||||
child: ColoredBox(
|
||||
color: ref.watch(themeProvider).themeColor.settingBgColor(),
|
||||
child: SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: Stack(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
child: Image.asset(
|
||||
"assets/images/login_bg.png",
|
||||
width: MediaQuery.of(context).size.width,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
),
|
||||
),
|
||||
Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 8,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
useSecretLogin ? "client_id登录" : "账号登录",
|
||||
style: TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onDoubleTap: () {
|
||||
if (debugBtnIsShow()) {
|
||||
dismissDebugBtn();
|
||||
} else {
|
||||
showDebugBtn(context, btnColor: ref.watch(themeProvider).primaryColor);
|
||||
}
|
||||
WidgetsBinding.instance.endOfFrame;
|
||||
},
|
||||
child: Image.asset(
|
||||
"assets/images/ql.png",
|
||||
height: 45,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 15,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 40,
|
||||
child: Text(
|
||||
"域名",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 30,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _hostController,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
hintText: "http://1.1.1.1:5700",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(
|
||||
color: Color(0xff999999),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
FlipCard(
|
||||
key: cardKey,
|
||||
flipOnTouch: false,
|
||||
onFlipDone: (back) {
|
||||
useSecretLogin = back;
|
||||
setState(() {});
|
||||
},
|
||||
direction: FlipDirection.HORIZONTAL,
|
||||
front: SizedBox(
|
||||
height: 110,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Image.asset(
|
||||
"assets/images/login_tip.png",
|
||||
height: 45,
|
||||
const SizedBox(
|
||||
child: Text(
|
||||
"账户",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
width: 40,
|
||||
),
|
||||
GestureDetector(
|
||||
onDoubleTap: () {
|
||||
if (debugBtnIsShow()) {
|
||||
dismissDebugBtn();
|
||||
} else {
|
||||
showDebugBtn(context, btnColor: ref.watch(themeProvider).primaryColor);
|
||||
}
|
||||
WidgetsBinding.instance?.endOfFrame;
|
||||
},
|
||||
child: Image.asset(
|
||||
"assets/images/ql.png",
|
||||
height: 45,
|
||||
const SizedBox(
|
||||
width: 30,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _userNameController,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
hintText: "请输入账户",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 15,
|
||||
),
|
||||
const Text(
|
||||
"域名:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _hostController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "http://1.1.1.1:5700",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
FlipCard(
|
||||
key: cardKey,
|
||||
flipOnTouch: false,
|
||||
onFlipDone: (back) {
|
||||
useSecretLogin = back;
|
||||
setState(() {});
|
||||
},
|
||||
direction: FlipDirection.HORIZONTAL,
|
||||
front: SizedBox(
|
||||
height: 200,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"用户名:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _userNameController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入用户名",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"密码:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入密码",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
back: SizedBox(
|
||||
height: 200,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"client_id:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _cIdController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入client_id",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"client_secret:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _cSecretController,
|
||||
obscureText: true,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入client_secret",
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: rememberPassword,
|
||||
onChanged: (checked) {
|
||||
rememberPassword = checked ?? false;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"记住密码/client",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
cardKey.currentState?.toggleCard();
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
loginByUserName() ? "client_id登录" : "账号登录",
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: Color(0xff999999),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 40,
|
||||
child: Text(
|
||||
"密码",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 30,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
hintText: "请输入密码",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(
|
||||
color: Color(0xff999999),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
back: SizedBox(
|
||||
height: 110,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 40,
|
||||
child: Text(
|
||||
"id",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 30,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _cIdController,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
hintText: "请输入client_id",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(
|
||||
color: Color(0xff999999),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 50,
|
||||
child: Text(
|
||||
"secret",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _cSecretController,
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
hintText: "请输入client_secret",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(
|
||||
color: Color(0xff999999),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 80,
|
||||
child: IgnorePointer(
|
||||
ignoring: !canClickLoginBtn(),
|
||||
child: CupertinoButton(
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: rememberPassword,
|
||||
onChanged: (checked) {
|
||||
rememberPassword = checked ?? false;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"记住密码",
|
||||
style: TextStyle(
|
||||
color: Color(0xff555555),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
cardKey.currentState?.toggleCard();
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
loginByUserName() ? "client_id登录" : "账号登录",
|
||||
style: const TextStyle(
|
||||
color: Color(0xff555555),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Shake(
|
||||
preferences: const AnimationPreferences(autoPlay: AnimationPlayStates.None),
|
||||
key: loginKey,
|
||||
child: Center(
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: canClickLoginBtn()
|
||||
? [
|
||||
const Color(0xff5DD16F),
|
||||
const Color(0xff089556),
|
||||
]
|
||||
: [
|
||||
const Color(0xff5DD16F).withOpacity(0.6),
|
||||
const Color(0xff089556).withOpacity(0.6),
|
||||
],
|
||||
),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(10),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 80,
|
||||
child: IgnorePointer(
|
||||
ignoring: !canClickLoginBtn(),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return CupertinoButton(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 5,
|
||||
),
|
||||
color: canClickLoginBtn() ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).primaryColor.withOpacity(0.4),
|
||||
child: isLoading
|
||||
? const CupertinoActivityIndicator()
|
||||
: const Text(
|
||||
"登 录",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontSize: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
onPressed: () async {
|
||||
Http.pushedLoginPage = false;
|
||||
Utils.hideKeyBoard(context);
|
||||
if (loginByUserName()) {
|
||||
@@ -351,22 +474,22 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
login(_cIdController.text, _cSecretController.text);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 10,
|
||||
child: (getIt<UserInfoViewModel>().historyAccounts.isEmpty)
|
||||
? const SizedBox.shrink()
|
||||
: SizedBox(
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
(getIt<UserInfoViewModel>().historyAccounts.isEmpty)
|
||||
? const SizedBox.shrink()
|
||||
: SafeArea(
|
||||
top: false,
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Center(
|
||||
child: Material(
|
||||
@@ -378,24 +501,39 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<UserInfoBean>>[
|
||||
...getIt<UserInfoViewModel>()
|
||||
.historyAccounts
|
||||
.map((e) => PopupMenuItem<UserInfoBean>(
|
||||
value: e,
|
||||
child: buildCell(e),
|
||||
))
|
||||
.map(
|
||||
(e) => PopupMenuItem<UserInfoBean>(
|
||||
value: e,
|
||||
child: buildCell(context, e),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
],
|
||||
child: Text(
|
||||
"切换账号",
|
||||
style: TextStyle(
|
||||
color: ref.watch(themeProvider).primaryColor,
|
||||
fontSize: 14,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/icon_history.png",
|
||||
fit: BoxFit.cover,
|
||||
width: 16,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
const Text(
|
||||
"历史账号",
|
||||
style: TextStyle(
|
||||
color: Color(0xff555555),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -434,6 +572,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
|
||||
void loginFailed() {
|
||||
isLoading = false;
|
||||
loginKey.currentState?.forward();
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@@ -512,7 +651,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
});
|
||||
}
|
||||
|
||||
Widget buildCell(UserInfoBean bean) {
|
||||
Widget buildCell(BuildContext context, UserInfoBean bean) {
|
||||
return ListTile(
|
||||
title: Text(
|
||||
bean.host ?? "",
|
||||
@@ -525,6 +664,19 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
bean.userName ?? "",
|
||||
),
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
trailing: GestureDetector(
|
||||
onTap: () {
|
||||
getIt<UserInfoViewModel>().removeHistoryAccount(bean.host);
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
child: const Icon(
|
||||
CupertinoIcons.clear_thick,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -534,7 +686,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
_cIdController.text = result.userName ?? "";
|
||||
_cSecretController.text = result.password ?? "";
|
||||
if (cardKey.currentState?.isFront ?? false) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
cardKey.currentState?.toggleCard();
|
||||
});
|
||||
}
|
||||
@@ -542,7 +694,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
_userNameController.text = result.userName ?? "";
|
||||
_passwordController.text = result.password ?? "";
|
||||
if (!(cardKey.currentState?.isFront ?? false)) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
cardKey.currentState?.toggleCard();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ class DependencyCell extends ConsumerWidget {
|
||||
}
|
||||
|
||||
void showLog(WidgetRef ref, String? sId) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
showCupertinoDialog(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoAlertDialog(
|
||||
|
||||
@@ -219,7 +219,7 @@ class _ScriptDetailPageState extends ConsumerState<ScriptDetailPage>
|
||||
? const Center(
|
||||
child: CupertinoActivityIndicator(),
|
||||
)
|
||||
: CodeWidget(
|
||||
: ScriptCodeWidget(
|
||||
content: content ?? "",
|
||||
),
|
||||
);
|
||||
@@ -265,3 +265,40 @@ class _ScriptDetailPageState extends ConsumerState<ScriptDetailPage>
|
||||
loadData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ScriptCodeWidget extends StatefulWidget {
|
||||
final String content;
|
||||
|
||||
const ScriptCodeWidget({
|
||||
Key? key,
|
||||
required this.content,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ScriptCodeWidget> createState() => _ScriptCodeWidgetState();
|
||||
}
|
||||
|
||||
class _ScriptCodeWidgetState extends State<ScriptCodeWidget>{
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SelectableText.rich(
|
||||
TextSpan(
|
||||
style: GoogleFonts.droidSansMono(fontSize: 14).apply(
|
||||
fontSizeFactor: 1,
|
||||
),
|
||||
children: <TextSpan>[
|
||||
DartSyntaxHighlighter(SyntaxHighlighterStyle.lightThemeStyle())
|
||||
.format(widget.content)
|
||||
],
|
||||
),
|
||||
style: DefaultTextStyle.of(context).style.apply(
|
||||
fontSizeFactor: 1,
|
||||
),
|
||||
selectionWidthStyle: BoxWidthStyle.max,
|
||||
selectionHeightStyle: BoxHeightStyle.max,
|
||||
autofocus: true,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class _ScriptEditPageState extends ConsumerState<ScriptEditPage> {
|
||||
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
focusNode.requestFocus();
|
||||
});
|
||||
}
|
||||
@@ -117,24 +117,10 @@ class _ScriptEditPageState extends ConsumerState<ScriptEditPage> {
|
||||
),
|
||||
body: SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 10,
|
||||
),
|
||||
child: CodeField(
|
||||
controller: _codeController!,
|
||||
expands: true,
|
||||
wrap: true,
|
||||
lineNumberStyle: LineNumberStyle(
|
||||
width: 0,
|
||||
margin: 0,
|
||||
textStyle: TextStyle(
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
),
|
||||
),
|
||||
background: ref.watch(themeProvider).themeColor.tabBarColor(),
|
||||
),
|
||||
child: CodeField(
|
||||
controller: _codeController!,
|
||||
expands: true,
|
||||
background: ref.watch(themeProvider).themeColor.tabBarColor(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -65,103 +65,112 @@ class _ScriptPageState extends ConsumerState<ScriptPage> with LazyLoadState<Scri
|
||||
),
|
||||
body: list.isEmpty
|
||||
? const Center(
|
||||
child: CupertinoActivityIndicator(),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
return searchCell(ref);
|
||||
}
|
||||
|
||||
ScriptBean item = list[index - 1];
|
||||
|
||||
if (_searchController.text.isEmpty ||
|
||||
(item.title?.contains(_searchController.text) ?? false) ||
|
||||
(item.value?.contains(_searchController.text) ?? false) ||
|
||||
((item.children?.where((e) {
|
||||
return (e.title?.contains(_searchController.text) ?? false) || (e.value?.contains(_searchController.text) ?? false);
|
||||
}).isNotEmpty ??
|
||||
false))) {
|
||||
return ColoredBox(
|
||||
color: ref.watch(themeProvider).themeColor.settingBgColor(),
|
||||
child: (item.children != null && item.children!.isNotEmpty)
|
||||
? ExpansionTile(
|
||||
title: Text(
|
||||
item.title ?? "",
|
||||
style: TextStyle(
|
||||
color: (item.disabled ?? false)
|
||||
? ref.watch(themeProvider).themeColor.descColor()
|
||||
: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
children: item.children!
|
||||
.where((element) {
|
||||
if (_searchController.text.isEmpty) {
|
||||
return true;
|
||||
child: CupertinoActivityIndicator(),
|
||||
)
|
||||
: RefreshIndicator(
|
||||
color: Theme.of(context).primaryColor,
|
||||
onRefresh: () async {
|
||||
await loadData();
|
||||
return Future.value();
|
||||
},
|
||||
child: ListView.builder(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
return searchCell(ref);
|
||||
}
|
||||
|
||||
ScriptBean item = list[index - 1];
|
||||
|
||||
if (_searchController.text.isEmpty ||
|
||||
(item.title?.contains(_searchController.text) ?? false) ||
|
||||
(item.value?.contains(_searchController.text) ?? false) ||
|
||||
((item.children?.where((e) {
|
||||
return (e.title?.contains(_searchController.text) ?? false) || (e.value?.contains(_searchController.text) ?? false);
|
||||
}).isNotEmpty ??
|
||||
false))) {
|
||||
return ColoredBox(
|
||||
color: ref.watch(themeProvider).themeColor.settingBgColor(),
|
||||
child: (item.children != null && item.children!.isNotEmpty)
|
||||
? ExpansionTile(
|
||||
title: Text(
|
||||
item.title ?? "",
|
||||
style: TextStyle(
|
||||
color: (item.disabled ?? false)
|
||||
? ref.watch(themeProvider).themeColor.descColor()
|
||||
: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
children: item.children!
|
||||
.where((element) {
|
||||
if (_searchController.text.isEmpty) {
|
||||
return true;
|
||||
}
|
||||
return (element.title?.contains(_searchController.text) ?? false) ||
|
||||
(element.value?.contains(_searchController.text) ?? false);
|
||||
})
|
||||
.map((e) => ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.routeScriptDetail,
|
||||
arguments: {
|
||||
"title": e.title,
|
||||
"path": e.parent,
|
||||
},
|
||||
).then((value) {
|
||||
if (value != null && value == true) {
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
},
|
||||
title: Text(
|
||||
e.title ?? "",
|
||||
style: TextStyle(
|
||||
color: (item.disabled ?? false)
|
||||
? ref.watch(themeProvider).themeColor.descColor()
|
||||
: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
)
|
||||
: ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.routeScriptDetail,
|
||||
arguments: {
|
||||
"title": item.title,
|
||||
"path": "",
|
||||
},
|
||||
).then(
|
||||
(value) {
|
||||
if (value != null && value == true) {
|
||||
loadData();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
item.title ?? "",
|
||||
style: TextStyle(
|
||||
color: (item.disabled ?? false)
|
||||
? ref.watch(themeProvider).themeColor.descColor()
|
||||
: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return (element.title?.contains(_searchController.text) ?? false) ||
|
||||
(element.value?.contains(_searchController.text) ?? false);
|
||||
})
|
||||
.map((e) => ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.routeScriptDetail,
|
||||
arguments: {
|
||||
"title": e.title,
|
||||
"path": e.parent,
|
||||
},
|
||||
).then((value) {
|
||||
if (value != null && value == true) {
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
},
|
||||
title: Text(
|
||||
e.title ?? "",
|
||||
style: TextStyle(
|
||||
color: (item.disabled ?? false)
|
||||
? ref.watch(themeProvider).themeColor.descColor()
|
||||
: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
)
|
||||
: ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.routeScriptDetail,
|
||||
arguments: {
|
||||
"title": item.title,
|
||||
"path": "",
|
||||
},
|
||||
).then(
|
||||
(value) {
|
||||
if (value != null && value == true) {
|
||||
loadData();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
item.title ?? "",
|
||||
style: TextStyle(
|
||||
color: (item.disabled ?? false)
|
||||
? ref.watch(themeProvider).themeColor.descColor()
|
||||
: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
itemCount: list.length + 1,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
itemCount: list.length + 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -171,7 +180,9 @@ class _ScriptPageState extends ConsumerState<ScriptPage> with LazyLoadState<Scri
|
||||
horizontal: 15,
|
||||
vertical: 10,
|
||||
),
|
||||
child:SearchCell(controller: _searchController,),
|
||||
child: SearchCell(
|
||||
controller: _searchController,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -220,61 +231,70 @@ class _ScriptPageState extends ConsumerState<ScriptPage> with LazyLoadState<Scri
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
child: TextField(
|
||||
controller: _nameController,
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.all(4),
|
||||
hintText: "请输入脚本名称",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: TextField(
|
||||
controller: _nameController,
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.all(4),
|
||||
hintText: "请输入脚本名称",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const Text(
|
||||
"脚本所属文件夹:",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
const Material(
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
"脚本所属文件夹:",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
DropdownButtonFormField<String>(
|
||||
items: list
|
||||
.where((element) => element.children?.isNotEmpty ?? false)
|
||||
.map((e) => DropdownMenuItem(
|
||||
value: e.value,
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2,
|
||||
child: Text(
|
||||
e.value ?? "",
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList()
|
||||
..insert(
|
||||
0,
|
||||
DropdownMenuItem(
|
||||
value: "",
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2,
|
||||
child: const Text(
|
||||
"根目录",
|
||||
maxLines: 2,
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: DropdownButtonFormField<String>(
|
||||
items: list
|
||||
.where((element) => element.children?.isNotEmpty ?? false)
|
||||
.map((e) => DropdownMenuItem(
|
||||
value: e.value,
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2,
|
||||
child: Text(
|
||||
e.value ?? "",
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList()
|
||||
..insert(
|
||||
0,
|
||||
DropdownMenuItem(
|
||||
value: "",
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width / 2,
|
||||
child: const Text(
|
||||
"根目录",
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
value: scriptPath,
|
||||
onChanged: (value) {
|
||||
scriptPath = value ?? "";
|
||||
},
|
||||
)),
|
||||
value: scriptPath,
|
||||
onChanged: (value) {
|
||||
scriptPath = value ?? "";
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -31,7 +31,7 @@ class _UpdatePasswordPageState extends ConsumerState<UpdatePasswordPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance?.addPostFrameCallback(
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(timeStamp) {
|
||||
focusNode.requestFocus();
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ class _AddTaskPageState extends ConsumerState<AddTaskPage> {
|
||||
} else {
|
||||
taskBean = TaskBean();
|
||||
}
|
||||
WidgetsBinding.instance?.addPostFrameCallback(
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(timeStamp) {
|
||||
focusNode.requestFocus();
|
||||
},
|
||||
|
||||
@@ -345,7 +345,7 @@ class _TaskDetailPageState extends ConsumerState<TaskDetailPage> {
|
||||
startCron(BuildContext context, WidgetRef ref) async {
|
||||
await ref.read(taskProvider).runCrons(widget.taskBean.sId!);
|
||||
setState(() {});
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
showLog();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ class TaskItemCell extends StatelessWidget {
|
||||
SlidableAction(
|
||||
backgroundColor: const Color(0xff5D5E70),
|
||||
onPressed: (_) {
|
||||
WidgetsBinding.instance?.endOfFrame.then((timeStamp) {
|
||||
WidgetsBinding.instance.endOfFrame.then((timeStamp) {
|
||||
Navigator.of(context).pushNamed(Routes.routeAddTask, arguments: bean);
|
||||
});
|
||||
},
|
||||
|
||||
35
pubspec.lock
35
pubspec.lock
@@ -42,7 +42,7 @@ packages:
|
||||
name: back_button_interceptor
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
version: "6.0.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -168,7 +168,7 @@ packages:
|
||||
name: collection
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -189,7 +189,7 @@ packages:
|
||||
name: cupertino_icons
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "1.0.5"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -224,7 +224,7 @@ packages:
|
||||
name: fake_async
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -258,6 +258,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_animator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_animator
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
flutter_app_name:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -311,7 +318,7 @@ packages:
|
||||
name: flutter_riverpod
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.4"
|
||||
flutter_slidable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -433,7 +440,7 @@ packages:
|
||||
name: js
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.6.3"
|
||||
version: "0.6.4"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -503,7 +510,7 @@ packages:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "0.1.4"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -580,7 +587,7 @@ packages:
|
||||
name: path
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.1"
|
||||
path_provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -781,7 +788,7 @@ packages:
|
||||
name: source_span
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
version: "1.8.2"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -837,7 +844,7 @@ packages:
|
||||
name: test_api
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.4.8"
|
||||
version: "0.4.9"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -865,7 +872,7 @@ packages:
|
||||
name: url_launcher
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
version: "6.1.3"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -921,7 +928,7 @@ packages:
|
||||
name: vector_math
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -972,5 +979,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.16.0 <3.0.0"
|
||||
flutter: ">=2.10.1"
|
||||
dart: ">=2.17.0-0 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
||||
21
pubspec.yaml
21
pubspec.yaml
@@ -13,13 +13,13 @@ dependencies:
|
||||
sdk: flutter
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
cupertino_icons: ^1.0.4
|
||||
flutter_riverpod: ^1.0.3
|
||||
shared_preferences: ^2.0.13
|
||||
synchronized: ^3.0.0
|
||||
back_button_interceptor: ^5.0.2
|
||||
flutter_slidable: ^1.2.0
|
||||
dio: ^4.0.4
|
||||
cupertino_icons: ^1.0.5
|
||||
flutter_riverpod: ^1.0.4
|
||||
shared_preferences: ^2.0.15
|
||||
synchronized: ^3.0.0+2
|
||||
back_button_interceptor: ^6.0.0
|
||||
flutter_slidable: ^1.3.0
|
||||
dio: ^4.0.6
|
||||
dio_log: ^2.0.2
|
||||
json_conversion_annotation: ^0.0.4
|
||||
logger: ^1.1.0
|
||||
@@ -27,14 +27,15 @@ dependencies:
|
||||
get_it: ^7.2.0
|
||||
highlight: ^0.7.0
|
||||
drag_and_drop_lists: ^0.3.2+2
|
||||
fluttertoast: ^8.0.8
|
||||
fluttertoast: ^8.0.9
|
||||
move_to_background: ^1.0.2
|
||||
flip_card: ^0.6.0
|
||||
package_info_plus: ^1.4.0
|
||||
url_launcher: ^6.0.20
|
||||
package_info_plus: ^1.4.2
|
||||
url_launcher: ^6.1.3
|
||||
flutter_colorpicker: ^1.0.3
|
||||
widget_with_codeview: ^2.0.1+2
|
||||
code_text_field: ^1.0.2
|
||||
flutter_animator: ^3.2.1
|
||||
|
||||
# flutter pub run build_runner build --delete-conflicting-outputs
|
||||
# flutter pub run change_app_package_name:main work.master.qinglongapp
|
||||
|
||||
Reference in New Issue
Block a user