mirror of
https://github.com/lifegpc/eh_downloader_flutter.git
synced 2026-07-08 01:30:28 +08:00
204 lines
6.8 KiB
Dart
204 lines
6.8 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:eh_downloader_flutter/l10n_gen/app_localizations.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:logging/logging.dart';
|
|
import '../api/user.dart';
|
|
import '../components/labeled_checkbox.dart';
|
|
import '../components/user_permissions_chips.dart';
|
|
import '../globals.dart';
|
|
|
|
final _log = Logger("NewUserPage");
|
|
|
|
class NewUserPage extends StatefulWidget {
|
|
const NewUserPage({super.key});
|
|
|
|
static const routeName = "/dialog/user/new";
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _NewUserPage();
|
|
}
|
|
|
|
class _NewUserPage extends State<NewUserPage> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
String _username = "";
|
|
String _password = "";
|
|
bool _isAdmin = false;
|
|
UserPermissions _permissions =
|
|
UserPermissions(UserPermission.readGallery.value);
|
|
bool _passwordVisible = false;
|
|
CancelToken? _cancel;
|
|
bool _isRequesting = false;
|
|
int? _newUserId;
|
|
|
|
Widget _buildWithVecticalPadding(Widget child) {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
|
child: child,
|
|
);
|
|
}
|
|
|
|
Future<void> _request() async {
|
|
setState(() {
|
|
_isRequesting = true;
|
|
});
|
|
try {
|
|
_cancel = CancelToken();
|
|
// 关闭对话框不中断连接
|
|
_newUserId = (await api.createUser(_username, _password,
|
|
isAdmin: _isAdmin,
|
|
permissions: _isAdmin ? null : _permissions.code))
|
|
.unwrap();
|
|
if (!_cancel!.isCancelled) {
|
|
setState(() {
|
|
_isRequesting = false;
|
|
});
|
|
}
|
|
listener.tryEmit("new_user", _newUserId);
|
|
} catch (e) {
|
|
_log.severe("Failed to create new user: $e");
|
|
if (!_cancel!.isCancelled) {
|
|
setState(() {
|
|
_isRequesting = false;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_cancel?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (!tryInitApi(context)) {
|
|
return Container();
|
|
}
|
|
if (auth.isAdmin == false) {
|
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
context.go("/");
|
|
});
|
|
return Container();
|
|
}
|
|
if (_newUserId != null) {
|
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
context.canPop() ? context.pop() : context.go("/users");
|
|
});
|
|
_newUserId = null;
|
|
return Container();
|
|
}
|
|
final i18n = AppLocalizations.of(context)!;
|
|
final maxWidth = MediaQuery.of(context).size.width;
|
|
if (auth.noUser == true) {
|
|
_isAdmin = true;
|
|
}
|
|
return Container(
|
|
padding: maxWidth < 400
|
|
? const EdgeInsets.symmetric(vertical: 20, horizontal: 5)
|
|
: const EdgeInsets.all(20),
|
|
width: maxWidth < 810 ? null : 800,
|
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
|
|
child: SingleChildScrollView(
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
Text(
|
|
i18n.createNewUser,
|
|
style: Theme.of(context).textTheme.headlineSmall,
|
|
),
|
|
Align(
|
|
alignment: Alignment.centerRight,
|
|
child: IconButton(
|
|
onPressed: () => context.canPop()
|
|
? context.pop()
|
|
: context.go("/users"),
|
|
icon: const Icon(Icons.close),
|
|
)),
|
|
],
|
|
),
|
|
_buildWithVecticalPadding(TextFormField(
|
|
decoration: InputDecoration(
|
|
border: const OutlineInputBorder(),
|
|
labelText: i18n.username,
|
|
),
|
|
initialValue: _username,
|
|
onChanged: (value) {
|
|
setState(() {
|
|
_username = value;
|
|
});
|
|
},
|
|
)),
|
|
_buildWithVecticalPadding(TextFormField(
|
|
decoration: InputDecoration(
|
|
border: const OutlineInputBorder(),
|
|
labelText: i18n.password,
|
|
suffixIcon: IconButton(
|
|
icon: Icon(
|
|
_passwordVisible
|
|
? Icons.visibility
|
|
: Icons.visibility_off,
|
|
color: Theme.of(context).primaryColorDark,
|
|
),
|
|
onPressed: () {
|
|
setState(() {
|
|
_passwordVisible = !_passwordVisible;
|
|
});
|
|
},
|
|
),
|
|
),
|
|
initialValue: _password,
|
|
onChanged: (value) {
|
|
setState(() {
|
|
_password = value;
|
|
});
|
|
},
|
|
obscureText: !_passwordVisible,
|
|
)),
|
|
auth.isRoot == true || auth.noUser == true
|
|
? _buildWithVecticalPadding(LabeledCheckbox(
|
|
value: _isAdmin,
|
|
onChanged: auth.noUser == true
|
|
? null
|
|
: (b) {
|
|
if (b != null) {
|
|
setState(() {
|
|
_isAdmin = b;
|
|
});
|
|
}
|
|
},
|
|
label: Text(i18n.admin)))
|
|
: Container(),
|
|
!_isAdmin
|
|
? _buildWithVecticalPadding(UserPermissionsChips(
|
|
permissions: _permissions,
|
|
onChanged: (v) {
|
|
setState(() {
|
|
_permissions = v;
|
|
});
|
|
}))
|
|
: Container(),
|
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
ElevatedButton(
|
|
onPressed: !_isRequesting &&
|
|
_username.isNotEmpty &&
|
|
_password.isNotEmpty
|
|
? () {
|
|
_request();
|
|
}
|
|
: null,
|
|
child: Text(i18n.create))
|
|
]),
|
|
],
|
|
))),
|
|
);
|
|
}
|
|
}
|