mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-07-23 22:51:00 -04:00
hud
This commit is contained in:
parent
8907ce04ac
commit
b7236befd1
8 changed files with 164 additions and 100 deletions
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:animated_theme_switcher/animated_theme_switcher.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'router/router.dart';
|
||||
import 'package:flutter_translate/flutter_translate.dart';
|
||||
|
||||
|
@ -32,6 +33,7 @@ class VeilidChatApp extends ConsumerWidget {
|
|||
localizationsDelegates: [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
FormBuilderLocalizations.delegate,
|
||||
localizationDelegate
|
||||
],
|
||||
supportedLocales: localizationDelegate.supportedLocales,
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_translate/flutter_translate.dart';
|
||||
|
||||
import '../components/default_app_bar.dart';
|
||||
import '../tools/desktop_control.dart';
|
||||
|
||||
class NewAccountForm extends ConsumerStatefulWidget {
|
||||
const NewAccountForm({super.key});
|
||||
|
||||
@override
|
||||
NewAccountFormState createState() {
|
||||
return NewAccountFormState();
|
||||
}
|
||||
}
|
||||
|
||||
class NewAccountFormState extends ConsumerState<NewAccountForm> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
key: const ValueKey("name"),
|
||||
autofocus: true,
|
||||
decoration:
|
||||
InputDecoration(hintText: translate("new_account_form.name")),
|
||||
maxLength: 64,
|
||||
// The validator receives the text that the user has entered.
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Name is required';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
key: const ValueKey("title"),
|
||||
maxLength: 64,
|
||||
decoration:
|
||||
InputDecoration(hintText: translate("new_account_form.title")),
|
||||
),
|
||||
Row(children: [
|
||||
const Spacer(),
|
||||
Text(translate("new_account_form.instructions"))
|
||||
.toCenter()
|
||||
.flexible(flex: 4),
|
||||
const Spacer(),
|
||||
]).paddingSymmetric(vertical: 24),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// Validate returns true if the form is valid, or false otherwise.
|
||||
if (_formKey.currentState!.validate()) {
|
||||
// If the form is valid, display a snackbar. In the real world,
|
||||
// you'd often call a server or save the information in a database.
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Processing Data')),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(translate('new_account_form.create')),
|
||||
).paddingSymmetric(vertical: 16).toCenter(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,37 +1,104 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_translate/flutter_translate.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
|
||||
import '../components/default_app_bar.dart';
|
||||
import '../components/new_account_form.dart';
|
||||
import '../providers/local_accounts.dart';
|
||||
import '../tools/tools.dart';
|
||||
|
||||
class NewAccountPage extends ConsumerWidget {
|
||||
class NewAccountPage extends ConsumerStatefulWidget {
|
||||
const NewAccountPage({super.key});
|
||||
static const path = '/new_account';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
enableTitleBar(true);
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: DefaultAppBar(context,
|
||||
title: Text(translate("new_account_page.title"))),
|
||||
body: Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Text(translate("new_account_page.header"))
|
||||
.textStyle(context.headlineSmall)
|
||||
.paddingSymmetric(vertical: 16),
|
||||
const NewAccountForm().flexible(),
|
||||
Text(translate("new_account_page.import"))
|
||||
],
|
||||
),
|
||||
));
|
||||
NewAccountPageState createState() {
|
||||
return NewAccountPageState();
|
||||
}
|
||||
}
|
||||
|
||||
class NewAccountPageState extends ConsumerState<NewAccountPage> {
|
||||
final _formKey = GlobalKey<FormBuilderState>();
|
||||
late bool isInAsyncCall = false;
|
||||
|
||||
Widget _newAccountForm(BuildContext context,
|
||||
{required Future<void> Function(GlobalKey<FormBuilderState>) onSubmit}) {
|
||||
return FormBuilder(
|
||||
key: _formKey,
|
||||
child: ListView(
|
||||
children: [
|
||||
Text(translate("new_account_page.header"))
|
||||
.textStyle(context.headlineSmall)
|
||||
.paddingSymmetric(vertical: 16),
|
||||
FormBuilderTextField(
|
||||
autofocus: true,
|
||||
name: 'name',
|
||||
decoration: InputDecoration(
|
||||
hintText: translate("new_account_page.form_name")),
|
||||
maxLength: 64,
|
||||
// The validator receives the text that the user has entered.
|
||||
validator: FormBuilderValidators.compose([
|
||||
FormBuilderValidators.required(),
|
||||
]),
|
||||
),
|
||||
FormBuilderTextField(
|
||||
name: 'title',
|
||||
maxLength: 64,
|
||||
decoration: InputDecoration(
|
||||
hintText: translate("new_account_page.form_title")),
|
||||
),
|
||||
Row(children: [
|
||||
const Spacer(),
|
||||
Text(translate("new_account_page.instructions"))
|
||||
.toCenter()
|
||||
.flexible(flex: 6),
|
||||
const Spacer(),
|
||||
]).paddingSymmetric(vertical: 4),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState?.saveAndValidate() ?? false) {
|
||||
setState(() {
|
||||
isInAsyncCall = true;
|
||||
});
|
||||
try {
|
||||
await onSubmit(_formKey);
|
||||
} finally {
|
||||
setState(() {
|
||||
isInAsyncCall = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Text(translate('new_account_page.create')),
|
||||
).paddingSymmetric(vertical: 4).alignAtCenterRight(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
enableTitleBar(true);
|
||||
portraitOnly();
|
||||
|
||||
final localAccounts = ref.watch(localAccountsProvider);
|
||||
|
||||
return Scaffold(
|
||||
// resizeToAvoidBottomInset: false,
|
||||
appBar: DefaultAppBar(context,
|
||||
title: Text(translate("new_account_page.titlebar"))),
|
||||
body: _newAccountForm(
|
||||
context,
|
||||
onSubmit: (formKey) async {
|
||||
debugPrint(_formKey.currentState?.value.toString());
|
||||
FocusScope.of(context).unfocus();
|
||||
await Future.delayed(Duration(seconds: 5));
|
||||
},
|
||||
).paddingSymmetric(horizontal: 24, vertical: 8),
|
||||
).withModalHUD(context, isInAsyncCall);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:io';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
Future<void> setupDesktopWindow() async {
|
||||
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
||||
|
@ -30,3 +31,17 @@ void enableTitleBar(bool enabled) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void portraitOnly() {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
DeviceOrientation.portraitDown,
|
||||
]);
|
||||
}
|
||||
|
||||
void landscapeOnly() {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:blurry_modal_progress_hud/blurry_modal_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
extension BorderExt on Widget {
|
||||
Container debugBorder() {
|
||||
|
@ -7,3 +9,19 @@ extension BorderExt on Widget {
|
|||
child: this);
|
||||
}
|
||||
}
|
||||
|
||||
extension ModalProgressExt on Widget {
|
||||
BlurryModalProgressHUD withModalHUD(BuildContext context, bool isLoading) {
|
||||
return BlurryModalProgressHUD(
|
||||
inAsyncCall: isLoading,
|
||||
blurEffectIntensity: 4,
|
||||
progressIndicator: SpinKitFoldingCube(
|
||||
color: Theme.of(context).highlightColor,
|
||||
size: 90.0,
|
||||
),
|
||||
dismissible: false,
|
||||
opacity: 0.3,
|
||||
color: Theme.of(context).shadowColor,
|
||||
child: this);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue