mirror of
https://github.com/lifegpc/eh_downloader_flutter.git
synced 2026-07-08 01:30:28 +08:00
Add Settings Page
This commit is contained in:
@@ -14,6 +14,8 @@ class AuthInfo {
|
||||
bool get isAuthed => (_user != null);
|
||||
bool _checked = false;
|
||||
bool get checked => _checked;
|
||||
bool _isChecking = false;
|
||||
bool get isChecking => _isChecking;
|
||||
|
||||
void clear() {
|
||||
_user = null;
|
||||
@@ -26,20 +28,25 @@ class AuthInfo {
|
||||
}
|
||||
|
||||
Future<bool> checkAuth() async {
|
||||
final re = await api.getUser();
|
||||
if (re.ok) {
|
||||
_user = re.data!;
|
||||
final u = _user!;
|
||||
_log.info(
|
||||
"Logged in as ${u.username} (${u.id}). isAdmin: ${u.isAdmin}. permissions: ${u.permissions}");
|
||||
} else if (re.status == 401 || re.status == 1 || re.status == 404) {
|
||||
_user = null;
|
||||
} else {
|
||||
_user = null;
|
||||
throw re.unwrapErr();
|
||||
_isChecking = true;
|
||||
try {
|
||||
final re = await api.getUser();
|
||||
if (re.ok) {
|
||||
_user = re.data!;
|
||||
final u = _user!;
|
||||
_log.info(
|
||||
"Logged in as ${u.username} (${u.id}). isAdmin: ${u.isAdmin}. permissions: ${u.permissions}");
|
||||
} else if (re.status == 401 || re.status == 1 || re.status == 404) {
|
||||
_user = null;
|
||||
} else {
|
||||
_user = null;
|
||||
throw re.unwrapErr();
|
||||
}
|
||||
_checked = true;
|
||||
await getServerStatus();
|
||||
return re.ok;
|
||||
} finally {
|
||||
_isChecking = false;
|
||||
}
|
||||
_checked = true;
|
||||
await getServerStatus();
|
||||
return re.ok;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
import 'package:cookie_jar/cookie_jar.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
@@ -115,6 +116,7 @@ final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey =
|
||||
enum MoreVertSettings {
|
||||
setServerUrl,
|
||||
createRootUser,
|
||||
settings,
|
||||
}
|
||||
|
||||
void onMoreVertSettingsSelected(BuildContext context, MoreVertSettings value) {
|
||||
@@ -125,6 +127,9 @@ void onMoreVertSettingsSelected(BuildContext context, MoreVertSettings value) {
|
||||
case MoreVertSettings.createRootUser:
|
||||
context.push("/create_root_user");
|
||||
break;
|
||||
case MoreVertSettings.settings:
|
||||
context.push("/settings");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -148,6 +153,11 @@ List<PopupMenuEntry<MoreVertSettings>> buildMoreVertSettings(
|
||||
value: MoreVertSettings.createRootUser,
|
||||
child: Text(AppLocalizations.of(context)!.createRootUser)));
|
||||
}
|
||||
if (path != "/settings") {
|
||||
list.add(PopupMenuItem(
|
||||
value: MoreVertSettings.settings,
|
||||
child: Text(AppLocalizations.of(context)!.settings)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -184,3 +194,22 @@ mixin ThemeModeWidget<T extends StatefulWidget> on State<T> {
|
||||
: Icons.light_mode));
|
||||
}
|
||||
}
|
||||
|
||||
enum Lang {
|
||||
system("System"),
|
||||
english("English"),
|
||||
simplifiedChinese("简体中文");
|
||||
|
||||
const Lang(String lang) : langName = lang;
|
||||
final String langName;
|
||||
Locale toLocale() {
|
||||
switch (this) {
|
||||
case Lang.english:
|
||||
return const Locale("en");
|
||||
case Lang.simplifiedChinese:
|
||||
return const Locale("zh");
|
||||
default:
|
||||
return PlatformDispatcher.instance.locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@ class HomePage extends HookWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (tryInitApi(context) && !auth.isAuthed && !auth.checked) {
|
||||
if (tryInitApi(context) &&
|
||||
!auth.isAuthed &&
|
||||
!auth.checked &&
|
||||
!auth.isChecking) {
|
||||
auth.checkAuth().then((re) {
|
||||
if (!re) {
|
||||
if (auth.status!.noUser &&
|
||||
|
||||
@@ -13,5 +13,9 @@
|
||||
"setServerUrl": "Server URL Settings",
|
||||
"createRootUser": "Create Root User",
|
||||
"skip": "Skip",
|
||||
"create": "Create"
|
||||
"create": "Create",
|
||||
"settings": "Settings",
|
||||
"lang": "Language",
|
||||
"systemLang": "System Language",
|
||||
"reset": "Reset"
|
||||
}
|
||||
|
||||
@@ -13,5 +13,9 @@
|
||||
"setServerUrl": "服务器地址设置",
|
||||
"createRootUser": "创建根用户",
|
||||
"skip": "跳过",
|
||||
"create": "创建"
|
||||
"create": "创建",
|
||||
"settings": "设置",
|
||||
"lang": "语言",
|
||||
"systemLang": "系统语言",
|
||||
"reset": "重置"
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'home.dart';
|
||||
import 'login.dart';
|
||||
import 'logs/file.dart';
|
||||
import 'set_server.dart';
|
||||
import 'settings.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
final _router = GoRouter(
|
||||
@@ -33,6 +34,10 @@ final _router = GoRouter(
|
||||
GoRoute(
|
||||
path: CreateRootUserPage.routeName,
|
||||
builder: (context, state) => const CreateRootUserPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: SettingsPage.routeName,
|
||||
builder: (context, state) => const SettingsPage(),
|
||||
)
|
||||
],
|
||||
);
|
||||
@@ -99,6 +104,8 @@ class _MainApp extends State<MainApp> {
|
||||
ThemeData _themeData = ThemeData();
|
||||
ThemeData _darkThemeData = ThemeData.dark();
|
||||
ThemeMode get themeMode => _themeMode;
|
||||
Lang _lang = Lang.system;
|
||||
Lang get lang => lang;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -108,6 +115,11 @@ class _MainApp extends State<MainApp> {
|
||||
} catch (e) {
|
||||
_log.warning("Failed to read themeMode from prefs:", e);
|
||||
}
|
||||
try {
|
||||
_lang = Lang.values[prefs.getInt("lang") ?? 0];
|
||||
} catch (e) {
|
||||
_log.warning("Failed to read lang from prefs:", e);
|
||||
}
|
||||
if (kIsWeb || isWindows) {
|
||||
_themeData = _themeData.useSystemChineseFont();
|
||||
_darkThemeData = _darkThemeData.useSystemChineseFont();
|
||||
@@ -125,6 +137,7 @@ class _MainApp extends State<MainApp> {
|
||||
}
|
||||
return title;
|
||||
},
|
||||
locale: _lang.toLocale(),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
theme: _themeData,
|
||||
@@ -141,4 +154,10 @@ class _MainApp extends State<MainApp> {
|
||||
_themeMode = mode;
|
||||
});
|
||||
}
|
||||
|
||||
void changeLang(Lang lang) {
|
||||
setState(() {
|
||||
_lang = lang;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
144
lib/settings.dart
Normal file
144
lib/settings.dart
Normal file
@@ -0,0 +1,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'globals.dart';
|
||||
import 'main.dart';
|
||||
|
||||
final _log = Logger("SettingsPage");
|
||||
|
||||
class SettingsPage extends StatefulWidget {
|
||||
const SettingsPage({Key? key}) : super(key: key);
|
||||
|
||||
static const String routeName = '/settings';
|
||||
|
||||
@override
|
||||
State<SettingsPage> createState() => _SettingsPage();
|
||||
}
|
||||
|
||||
class _SettingsPage extends State<SettingsPage> with ThemeModeWidget {
|
||||
Lang _ori_lang = Lang.system;
|
||||
Lang _lang = Lang.system;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
try {
|
||||
_ori_lang = Lang.values[prefs.getInt("lang") ?? 0];
|
||||
_lang = _ori_lang;
|
||||
} catch (e) {
|
||||
_log.warning("Failed to get lang:", e);
|
||||
_ori_lang = Lang.system;
|
||||
_lang = Lang.system;
|
||||
}
|
||||
}
|
||||
|
||||
void fallback(BuildContext context) {
|
||||
if (_ori_lang != _lang) {
|
||||
MainApp.of(context).changeLang(_ori_lang);
|
||||
}
|
||||
}
|
||||
|
||||
void reset(BuildContext context) {
|
||||
if (_lang != Lang.system) MainApp.of(context).changeLang(Lang.system);
|
||||
setState(() {
|
||||
_lang = Lang.system;
|
||||
});
|
||||
}
|
||||
|
||||
Future<bool> save() async {
|
||||
bool re = true;
|
||||
if (!await prefs.setInt("lang", _lang.index)) {
|
||||
re = false;
|
||||
_log.warning("Failed to save lang.");
|
||||
} else {
|
||||
_ori_lang = _lang;
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
fallback(context);
|
||||
context.canPop() ? context.pop() : context.go("/");
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
),
|
||||
title: Text(AppLocalizations.of(context)!.settings),
|
||||
actions: [
|
||||
buildThemeModeIcon(context),
|
||||
buildMoreVertSettingsButon(context),
|
||||
],
|
||||
),
|
||||
body: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return SingleChildScrollView(
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(minHeight: constraints.maxHeight),
|
||||
child: Container(
|
||||
padding: MediaQuery.of(context).size.width > 810
|
||||
? const EdgeInsets.symmetric(horizontal: 100)
|
||||
: null,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8),
|
||||
child: DropdownMenu<Lang>(
|
||||
initialSelection: _lang,
|
||||
onSelected: (value) {
|
||||
if (value != null) {
|
||||
setState(() {
|
||||
_lang = value;
|
||||
});
|
||||
MainApp.of(context).changeLang(_lang);
|
||||
}
|
||||
},
|
||||
label:
|
||||
Text(AppLocalizations.of(context)!.lang),
|
||||
dropdownMenuEntries: Lang.values
|
||||
.map((e) => DropdownMenuEntry(
|
||||
value: e,
|
||||
label: e == Lang.system
|
||||
? AppLocalizations.of(context)!
|
||||
.systemLang
|
||||
: e.langName))
|
||||
.toList(),
|
||||
leadingIcon: const Icon(Icons.language),
|
||||
)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
reset(context);
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.reset))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
save();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.save),
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
))));
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user