mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
添加关于页面
This commit is contained in:
@@ -6,6 +6,7 @@ import 'package:qinglong_app/module/env/env_bean.dart';
|
||||
import 'package:qinglong_app/module/env/env_detail_page.dart';
|
||||
import 'package:qinglong_app/module/home/home_page.dart';
|
||||
import 'package:qinglong_app/module/login/login_page.dart';
|
||||
import 'package:qinglong_app/module/others/about_page.dart';
|
||||
import 'package:qinglong_app/module/others/dependencies/add_dependency_page.dart';
|
||||
import 'package:qinglong_app/module/others/dependencies/dependency_page.dart';
|
||||
import 'package:qinglong_app/module/others/login_log/login_log_page.dart';
|
||||
@@ -37,6 +38,7 @@ class Routes {
|
||||
static const String routeScriptAdd = "/script/add";
|
||||
static const String routeDependency = "/Dependency";
|
||||
static const String routeUpdatePassword = "/updatePassword";
|
||||
static const String routeAbout = "/about";
|
||||
|
||||
static Route<dynamic>? generateRoute(RouteSettings settings) {
|
||||
switch (settings.name) {
|
||||
@@ -116,6 +118,10 @@ class Routes {
|
||||
return CupertinoPageRoute(
|
||||
builder: (context) => const UpdatePasswordPage(),
|
||||
);
|
||||
case routeAbout:
|
||||
return CupertinoPageRoute(
|
||||
builder: (context) => const AboutPage(),
|
||||
);
|
||||
case routeScriptUpdate:
|
||||
return CupertinoPageRoute(
|
||||
builder: (context) => ScriptEditPage(
|
||||
|
||||
@@ -54,22 +54,25 @@ class QlAppState extends ConsumerState<QlApp> {
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
child: MaterialApp(
|
||||
locale: const Locale('zh', 'cn'),
|
||||
navigatorKey: navigatorState,
|
||||
theme: ref.watch<ThemeViewModel>(themeProvider).currentTheme,
|
||||
onGenerateRoute: (setting) {
|
||||
return Routes.generateRoute(setting);
|
||||
},
|
||||
home: Builder(
|
||||
builder: (context) {
|
||||
if (!kReleaseMode) {
|
||||
showDebugBtn(context, btnColor: Colors.blue);
|
||||
}
|
||||
return getIt<UserInfoViewModel>().isLogined() ? const HomePage() : const LoginPage();
|
||||
child: MediaQuery(
|
||||
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window).copyWith(textScaleFactor: 1,),
|
||||
child: MaterialApp(
|
||||
locale: const Locale('zh', 'cn'),
|
||||
navigatorKey: navigatorState,
|
||||
theme: ref.watch<ThemeViewModel>(themeProvider).currentTheme,
|
||||
onGenerateRoute: (setting) {
|
||||
return Routes.generateRoute(setting);
|
||||
},
|
||||
home: Builder(
|
||||
builder: (context) {
|
||||
if (!kReleaseMode) {
|
||||
showDebugBtn(context, btnColor: Colors.blue);
|
||||
}
|
||||
return getIt<UserInfoViewModel>().isLogined() ? const HomePage() : const LoginPage();
|
||||
},
|
||||
),
|
||||
// home: LoginPage(),
|
||||
),
|
||||
// home: LoginPage(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,194 +81,203 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 10,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Image.asset(
|
||||
"assets/images/login_tip.png",
|
||||
height: 45,
|
||||
),
|
||||
),
|
||||
const Positioned(
|
||||
top: 10,
|
||||
left: 0,
|
||||
child: Text(
|
||||
"登录",
|
||||
style: TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 0,
|
||||
child: Image.asset(
|
||||
"assets/images/ql.png",
|
||||
height: 45,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
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,
|
||||
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,
|
||||
),
|
||||
],
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.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,
|
||||
SizedBox(
|
||||
height: 50,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Image.asset(
|
||||
"assets/images/login_tip.png",
|
||||
height: 45,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
controller: _cIdController,
|
||||
decoration: const InputDecoration(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5),
|
||||
hintText: "请输入client_id",
|
||||
const Positioned(
|
||||
top: 10,
|
||||
left: 0,
|
||||
child: Text(
|
||||
"登录",
|
||||
style: TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
autofocus: false,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Text(
|
||||
"client_secret:",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 0,
|
||||
child: Image.asset(
|
||||
"assets/images/ql.png",
|
||||
height: 45,
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25,),
|
||||
child: Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: rememberPassword,
|
||||
@@ -298,12 +307,16 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10,),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
SizedBox(
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40,),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 80,
|
||||
child: IgnorePointer(
|
||||
ignoring: !canClickLoginBtn(),
|
||||
@@ -334,8 +347,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
128
lib/module/others/about_page.dart
Normal file
128
lib/module/others/about_page.dart
Normal file
@@ -0,0 +1,128 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:qinglong_app/base/theme.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../main.dart';
|
||||
|
||||
/// @author NewTab
|
||||
|
||||
class AboutPage extends ConsumerStatefulWidget {
|
||||
const AboutPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
ConsumerState createState() => _AboutPageState();
|
||||
}
|
||||
|
||||
class _AboutPageState extends ConsumerState<AboutPage> {
|
||||
String desc = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getInfo();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: QlAppBar(
|
||||
canBack: true,
|
||||
title: "关于",
|
||||
),
|
||||
body: SizedBox(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 10,
|
||||
),
|
||||
Image.asset(
|
||||
"assets/images/ql.png",
|
||||
height: 50,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"青龙",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
"Version ${desc}",
|
||||
style: TextStyle(
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
_launchURL("https://github.com/qinglong-app/qinglong_app/releases");
|
||||
},
|
||||
child: Text(
|
||||
"版本更新",
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
_launchURL("https://github.com/qinglong-app/qinglong_app");
|
||||
},
|
||||
child: Text(
|
||||
"项目地址",
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _launchURL(String _url) async {
|
||||
try {
|
||||
await launch(_url);
|
||||
} catch (e) {
|
||||
logger.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
void getInfo() async {
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
|
||||
String version = packageInfo.version;
|
||||
|
||||
desc = version;
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
@@ -252,6 +252,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15,
|
||||
right: 15,
|
||||
top: 5,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -266,13 +267,51 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
),
|
||||
const Spacer(),
|
||||
CupertinoSwitch(
|
||||
value: ref.watch(themeProvider).isInDartMode(),
|
||||
onChanged: (open) {
|
||||
ref.watch(themeProvider).changeThemeReal(open);
|
||||
}),
|
||||
value: ref.watch(themeProvider).isInDartMode(),
|
||||
onChanged: (open) {
|
||||
ref.watch(themeProvider).changeThemeReal(open);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
indent: 15,
|
||||
),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.routeAbout,
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15,
|
||||
right: 15,
|
||||
top: 5,
|
||||
bottom: 15,
|
||||
),
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user