mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-12-23 14:02:34 +01:00
refactor: MVC sign up view
This commit is contained in:
parent
76199418b2
commit
db19b37f72
@ -1,6 +1,7 @@
|
||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:fluffychat/controllers/homeserver_picker_controller.dart';
|
||||
import 'package:fluffychat/controllers/sign_up_controller.dart';
|
||||
import 'package:fluffychat/views/widgets/matrix.dart';
|
||||
import 'package:fluffychat/views/archive.dart';
|
||||
import 'package:fluffychat/views/chat.dart';
|
||||
@ -24,7 +25,6 @@ import 'package:fluffychat/views/settings_ignore_list.dart';
|
||||
import 'package:fluffychat/views/settings_multiple_emotes.dart';
|
||||
import 'package:fluffychat/views/settings_notifications.dart';
|
||||
import 'package:fluffychat/views/settings_style.dart';
|
||||
import 'package:fluffychat/views/sign_up.dart';
|
||||
import 'package:fluffychat/views/sign_up_password.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
71
lib/controllers/sign_up_controller.dart
Normal file
71
lib/controllers/sign_up_controller.dart
Normal file
@ -0,0 +1,71 @@
|
||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||
import 'package:fluffychat/views/sign_up_view.dart';
|
||||
|
||||
import 'package:fluffychat/views/widgets/matrix.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class SignUp extends StatefulWidget {
|
||||
@override
|
||||
SignUpController createState() => SignUpController();
|
||||
}
|
||||
|
||||
class SignUpController extends State<SignUp> {
|
||||
final TextEditingController usernameController = TextEditingController();
|
||||
String usernameError;
|
||||
bool loading = false;
|
||||
MatrixFile avatar;
|
||||
|
||||
void setAvatarAction() async {
|
||||
var file =
|
||||
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
|
||||
if (file != null) {
|
||||
setState(
|
||||
() => avatar = MatrixFile(
|
||||
bytes: file.toUint8List(),
|
||||
name: file.fileName,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void resetAvatarAction() => setState(() => avatar = null);
|
||||
|
||||
void signUpAction([_]) async {
|
||||
var matrix = Matrix.of(context);
|
||||
if (usernameController.text.isEmpty) {
|
||||
setState(() => usernameError = L10n.of(context).pleaseChooseAUsername);
|
||||
} else {
|
||||
setState(() => usernameError = null);
|
||||
}
|
||||
|
||||
if (usernameController.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
setState(() => loading = true);
|
||||
|
||||
final preferredUsername =
|
||||
usernameController.text.toLowerCase().trim().replaceAll(' ', '-');
|
||||
|
||||
try {
|
||||
await matrix.client.usernameAvailable(preferredUsername);
|
||||
} on MatrixException catch (exception) {
|
||||
setState(() => usernameError = exception.errorMessage);
|
||||
return setState(() => loading = false);
|
||||
} catch (exception) {
|
||||
setState(() => usernameError = exception.toString());
|
||||
return setState(() => loading = false);
|
||||
}
|
||||
setState(() => loading = false);
|
||||
await AdaptivePageLayout.of(context).pushNamed(
|
||||
'/signup/password/${Uri.encodeComponent(preferredUsername)}/${Uri.encodeComponent(usernameController.text)}',
|
||||
arguments: avatar,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SignUpView(this);
|
||||
}
|
@ -51,11 +51,13 @@ void main() async {
|
||||
}
|
||||
|
||||
class FluffyChatApp extends StatelessWidget {
|
||||
final Widget test;
|
||||
final Widget testWidget;
|
||||
final Client testClient;
|
||||
static final GlobalKey<AdaptivePageLayoutState> _apl =
|
||||
GlobalKey<AdaptivePageLayoutState>();
|
||||
|
||||
const FluffyChatApp({Key key, this.test}) : super(key: key);
|
||||
const FluffyChatApp({Key key, this.testWidget, this.testClient})
|
||||
: super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AdaptiveTheme(
|
||||
@ -75,13 +77,14 @@ class FluffyChatApp extends StatelessWidget {
|
||||
builder: (context) => Matrix(
|
||||
context: context,
|
||||
apl: _apl,
|
||||
testClient: testClient,
|
||||
child: Builder(
|
||||
builder: (context) => AdaptivePageLayout(
|
||||
key: _apl,
|
||||
safeAreaOnColumnView: false,
|
||||
onGenerateRoute: test == null
|
||||
onGenerateRoute: testWidget == null
|
||||
? FluffyRoutes(context).onGenerateRoute
|
||||
: (_) => ViewData(mainView: (_) => test),
|
||||
: (_) => ViewData(mainView: (_) => testWidget),
|
||||
dividerColor: Theme.of(context).dividerColor,
|
||||
columnWidth: FluffyThemes.columnWidth,
|
||||
dividerWidth: 1.0,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||
import 'package:fluffychat/controllers/sign_up_controller.dart';
|
||||
import 'package:fluffychat/views/widgets/fluffy_banner.dart';
|
||||
|
||||
import 'package:fluffychat/views/widgets/matrix.dart';
|
||||
@ -9,61 +8,13 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class SignUp extends StatefulWidget {
|
||||
@override
|
||||
_SignUpState createState() => _SignUpState();
|
||||
}
|
||||
class SignUpView extends StatelessWidget {
|
||||
final SignUpController controller;
|
||||
|
||||
class _SignUpState extends State<SignUp> {
|
||||
final TextEditingController usernameController = TextEditingController();
|
||||
String usernameError;
|
||||
bool loading = false;
|
||||
MatrixFile avatar;
|
||||
|
||||
void setAvatarAction() async {
|
||||
var file =
|
||||
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
|
||||
if (file != null) {
|
||||
setState(
|
||||
() => avatar = MatrixFile(
|
||||
bytes: file.toUint8List(),
|
||||
name: file.fileName,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void signUpAction(BuildContext context) async {
|
||||
var matrix = Matrix.of(context);
|
||||
if (usernameController.text.isEmpty) {
|
||||
setState(() => usernameError = L10n.of(context).pleaseChooseAUsername);
|
||||
} else {
|
||||
setState(() => usernameError = null);
|
||||
}
|
||||
|
||||
if (usernameController.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
setState(() => loading = true);
|
||||
|
||||
final preferredUsername =
|
||||
usernameController.text.toLowerCase().trim().replaceAll(' ', '-');
|
||||
|
||||
try {
|
||||
await matrix.client.usernameAvailable(preferredUsername);
|
||||
} on MatrixException catch (exception) {
|
||||
setState(() => usernameError = exception.errorMessage);
|
||||
return setState(() => loading = false);
|
||||
} catch (exception) {
|
||||
setState(() => usernameError = exception.toString());
|
||||
return setState(() => loading = false);
|
||||
}
|
||||
setState(() => loading = false);
|
||||
await AdaptivePageLayout.of(context).pushNamed(
|
||||
'/signup/password/${Uri.encodeComponent(preferredUsername)}/${Uri.encodeComponent(usernameController.text)}',
|
||||
arguments: avatar,
|
||||
);
|
||||
}
|
||||
const SignUpView(
|
||||
this.controller, {
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -71,7 +22,7 @@ class _SignUpState extends State<SignUp> {
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
leading: loading ? Container() : BackButton(),
|
||||
leading: controller.loading ? Container() : BackButton(),
|
||||
title: Text(
|
||||
Matrix.of(context)
|
||||
.client
|
||||
@ -89,15 +40,16 @@ class _SignUpState extends State<SignUp> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: TextField(
|
||||
readOnly: loading,
|
||||
readOnly: controller.loading,
|
||||
autocorrect: false,
|
||||
controller: usernameController,
|
||||
onSubmitted: (s) => signUpAction(context),
|
||||
autofillHints: loading ? null : [AutofillHints.newUsername],
|
||||
controller: controller.usernameController,
|
||||
onSubmitted: controller.signUpAction,
|
||||
autofillHints:
|
||||
controller.loading ? null : [AutofillHints.newUsername],
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.account_circle_outlined),
|
||||
hintText: L10n.of(context).username,
|
||||
errorText: usernameError,
|
||||
errorText: controller.usernameError,
|
||||
labelText: L10n.of(context).chooseAUsername,
|
||||
),
|
||||
),
|
||||
@ -105,30 +57,31 @@ class _SignUpState extends State<SignUp> {
|
||||
SizedBox(height: 8),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage:
|
||||
avatar == null ? null : MemoryImage(avatar.bytes),
|
||||
backgroundColor: avatar == null
|
||||
backgroundImage: controller.avatar == null
|
||||
? null
|
||||
: MemoryImage(controller.avatar.bytes),
|
||||
backgroundColor: controller.avatar == null
|
||||
? Theme.of(context).brightness == Brightness.dark
|
||||
? Color(0xff121212)
|
||||
: Colors.white
|
||||
: Theme.of(context).secondaryHeaderColor,
|
||||
child: avatar == null
|
||||
child: controller.avatar == null
|
||||
? Icon(Icons.camera_alt_outlined,
|
||||
color: Theme.of(context).primaryColor)
|
||||
: null,
|
||||
),
|
||||
trailing: avatar == null
|
||||
trailing: controller.avatar == null
|
||||
? null
|
||||
: Icon(
|
||||
Icons.close,
|
||||
color: Colors.red,
|
||||
),
|
||||
title: Text(avatar == null
|
||||
title: Text(controller.avatar == null
|
||||
? L10n.of(context).setAProfilePicture
|
||||
: L10n.of(context).discardPicture),
|
||||
onTap: avatar == null
|
||||
? setAvatarAction
|
||||
: () => setState(() => avatar = null),
|
||||
onTap: controller.avatar == null
|
||||
? controller.setAvatarAction
|
||||
: controller.resetAvatarAction,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Hero(
|
||||
@ -136,8 +89,8 @@ class _SignUpState extends State<SignUp> {
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: ElevatedButton(
|
||||
onPressed: loading ? null : () => signUpAction(context),
|
||||
child: loading
|
||||
onPressed: controller.loading ? null : controller.signUpAction,
|
||||
child: controller.loading
|
||||
? LinearProgressIndicator()
|
||||
: Text(
|
||||
L10n.of(context).signUp.toUpperCase(),
|
@ -43,10 +43,13 @@ class Matrix extends StatefulWidget {
|
||||
|
||||
final BuildContext context;
|
||||
|
||||
final Client testClient;
|
||||
|
||||
Matrix({
|
||||
this.child,
|
||||
@required this.apl,
|
||||
@required this.context,
|
||||
this.testClient,
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
@ -66,6 +69,8 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||
|
||||
BackgroundPush _backgroundPush;
|
||||
|
||||
bool get testMode => widget.testClient != null;
|
||||
|
||||
Map<String, dynamic> get shareContent => _shareContent;
|
||||
set shareContent(Map<String, dynamic> content) {
|
||||
_shareContent = content;
|
||||
@ -256,7 +261,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||
});
|
||||
});
|
||||
}
|
||||
client = FluffyClient();
|
||||
client = widget.testClient ?? FluffyClient();
|
||||
LoadingDialog.defaultTitle = L10n.of(context).loadingPleaseWait;
|
||||
LoadingDialog.defaultBackLabel = L10n.of(context).close;
|
||||
LoadingDialog.defaultOnError = (Object e) => e.toLocalizedString(context);
|
||||
|
@ -5,7 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Test if the widget can be created', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(FluffyChatApp(test: HomeserverPicker()));
|
||||
await tester.pumpWidget(FluffyChatApp(testWidget: HomeserverPicker()));
|
||||
|
||||
await tester.tap(find.byType(TextField));
|
||||
await tester.tap(find.byType(ElevatedButton));
|
||||
|
9
test/sign_up_test.dart
Normal file
9
test/sign_up_test.dart
Normal file
@ -0,0 +1,9 @@
|
||||
import 'package:fluffychat/controllers/sign_up_controller.dart';
|
||||
import 'package:fluffychat/main.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Test if the widget can be created', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(FluffyChatApp(testWidget: SignUp()));
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user