From 2e90e6343c4ffcd4f1e85451b66843066e666e3d Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Thu, 25 Aug 2022 08:39:42 +0200 Subject: [PATCH] improved login screen; improvements & bugfixes --- lib/locale/l10n/app_de.arb | 7 +- lib/locale/l10n/app_en.arb | 7 +- lib/screens/login_screen.dart | 159 +++++++++--------- .../main_screen/today_photo_button.dart | 15 +- lib/screens/timeline_screen/memory_view.dart | 16 +- lib/widgets/raw_memory_display.dart | 47 +++--- 6 files changed, 117 insertions(+), 134 deletions(-) diff --git a/lib/locale/l10n/app_de.arb b/lib/locale/l10n/app_de.arb index 7d4bc57..68ad06f 100644 --- a/lib/locale/l10n/app_de.arb +++ b/lib/locale/l10n/app_de.arb @@ -46,11 +46,10 @@ "loginScreenHelpText": "Melde dich an. Wenn du noch keinen Account besitzt, erstellen wir automatisch einen für dich.", "loginScreenFormEmailLabel": "E-Mail", "loginScreenFormPasswordLabel": "Passwort", - "loginScreenFormSubmitButton": "Anmelden", + "loginScreenFormLoginButton": "Anmelden", + "loginScreenFormSignUpButton": "Registrieren", "loginScreenLoginFailed": "E-Mail oder Passwort inkorrekt", - "loginScreenSignUpDialogTitle": "Registrieren", - "loginScreenSignUpDialogExplanation": "Wir haben deinen Account nicht gefunden. Möchtest du dich jetzt registrieren?", - "loginScreenSignUpDialogAffirmationLabel": "Jetzt registrieren", + "loginScreenSignUpFailed": "Registrierung fehlgeschlagen. Hast du eventuell schon einen Account?", "grantPermissionScreenTitle": "Berechtigungen erteilen", diff --git a/lib/locale/l10n/app_en.arb b/lib/locale/l10n/app_en.arb index 035b44e..52ef6c6 100644 --- a/lib/locale/l10n/app_en.arb +++ b/lib/locale/l10n/app_en.arb @@ -66,11 +66,10 @@ "loginScreenHelpText": "Sign in to your account. If you do not have one already, we will automatically set up one for you.", "loginScreenFormEmailLabel": "Email", "loginScreenFormPasswordLabel": "Password", - "loginScreenFormSubmitButton": "Login", + "loginScreenFormLoginButton": "Login", + "loginScreenFormSignUpButton": "Sign up", "loginScreenLoginFailed": "Email or password incorrect", - "loginScreenSignUpDialogTitle": "Sign up", - "loginScreenSignUpDialogExplanation": "We didn't find your account. Do you want to sign up now?", - "loginScreenSignUpDialogAffirmationLabel": "Sign me up now", + "loginScreenSignUpFailed": "Registration failed. Maybe you already have an account?", "grantPermissionScreenTitle": "Grant Permissions", diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index fd9fe6d..aa9a2ee 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -46,20 +46,22 @@ class _LoginScreenState extends AuthState with Loadable { super.dispose(); } - Future _signUp() async { - final response = await supabase.auth.signUp( - emailController.text.trim(), - passwordController.text, - ); - - final error = response.error; - - if (error != null) { - throw Exception(error); + Future _onAuthenticated() async { + if (!mounted) { + return; } + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ServerLoadingScreen(), + ), + ); } - Future _signIn() async { + Future signIn() async { + final localizations = AppLocalizations.of(context)!; + final response = await supabase.auth.signIn( email: emailController.text.trim(), password: passwordController.text, @@ -67,63 +69,46 @@ class _LoginScreenState extends AuthState with Loadable { final error = response.error; + if (!mounted) { + return; + } + if (error != null) { - throw Exception(error); - } - } - - Future _askWhetherToSignUp() { - final localizations = AppLocalizations.of(context)!; - - return showPlatformDialog( - context: context, - builder: (_) => PlatformAlertDialog( - title: Text(localizations.loginScreenSignUpDialogTitle), - content: Text(localizations.loginScreenSignUpDialogExplanation), - actions: [ - PlatformDialogAction( - child: Text(localizations.generalCancelButtonLabel), - onPressed: () => Navigator.pop(context, false), - ), - PlatformDialogAction( - child: Text(localizations.loginScreenSignUpDialogAffirmationLabel), - onPressed: () => Navigator.pop(context, true), - ), - ], - ), - ) as Future; - } - - Future signIn() async { - final localizations = AppLocalizations.of(context)!; - - try { - await _signIn(); - } catch (error) { - if (await _askWhetherToSignUp()) { - try { - await _signUp(); - } catch (error) { - if (mounted) { - context.showLongErrorSnackBar( - message: localizations.loginScreenLoginFailed, - ); - - passwordController.clear(); - } - return; - } - } - } - - if (mounted) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const ServerLoadingScreen(), - ), + context.showLongErrorSnackBar( + message: localizations.loginScreenLoginFailed, ); + + passwordController.clear(); + return; } + + _onAuthenticated(); + } + + Future signUp() async { + final localizations = AppLocalizations.of(context)!; + + final response = await supabase.auth.signUp( + emailController.text.trim(), + passwordController.text, + ); + + final error = response.error; + + if (!mounted) { + return; + } + + if (error != null) { + context.showLongErrorSnackBar( + message: localizations.loginScreenSignUpFailed, + ); + + passwordController.clear(); + return; + } + + _onAuthenticated(); } @override @@ -148,16 +133,18 @@ class _LoginScreenState extends AuthState with Loadable { cupertino: (data) => data.textTheme.navLargeTitleTextStyle, ), ), - const SizedBox(height: LARGE_SPACE), - Text( - localizations.loginScreenHelpText, - style: platformThemeData( - context, - material: (data) => data.textTheme.bodyText1, - cupertino: (data) => data.textTheme.textStyle, + const Flexible(child: SizedBox(height: LARGE_SPACE)), + Flexible( + child: Text( + localizations.loginScreenHelpText, + style: platformThemeData( + context, + material: (data) => data.textTheme.bodyText1, + cupertino: (data) => data.textTheme.textStyle, + ), ), ), - const SizedBox(height: MEDIUM_SPACE), + const Flexible(child: SizedBox(height: MEDIUM_SPACE)), PlatformTextField( controller: emailController, autofocus: true, @@ -191,13 +178,25 @@ class _LoginScreenState extends AuthState with Loadable { ), onSubmitted: (value) => callWithLoading(signIn), ), - const SizedBox(height: MEDIUM_SPACE), - PlatformElevatedButton( - onPressed: isLoading ? null : () => callWithLoading(signIn), - child: IconButtonChild( - icon: Icon(context.platformIcons.forward), - label: Text(localizations.loginScreenFormSubmitButton), - ), + const Flexible(child: SizedBox(height: MEDIUM_SPACE)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + PlatformElevatedButton( + onPressed: isLoading ? null : () => callWithLoading(signIn), + child: IconButtonChild( + icon: Icon(context.platformIcons.forward), + label: Text(localizations.loginScreenFormLoginButton), + ), + ), + PlatformTextButton( + onPressed: isLoading ? null : () => callWithLoading(signUp), + child: IconButtonChild( + icon: Icon(context.platformIcons.add), + label: Text(localizations.loginScreenFormSignUpButton), + ), + ), + ], ), ], ), diff --git a/lib/screens/main_screen/today_photo_button.dart b/lib/screens/main_screen/today_photo_button.dart index 2aa4ab7..26bc44b 100644 --- a/lib/screens/main_screen/today_photo_button.dart +++ b/lib/screens/main_screen/today_photo_button.dart @@ -1,4 +1,4 @@ -import 'dart:typed_data'; +import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -25,7 +25,7 @@ class TodayPhotoButton extends StatefulWidget { } class _TodayPhotoButtonState extends State { - Uint8List? data; + File? file; MemoryType? type; @override @@ -59,7 +59,7 @@ class _TodayPhotoButtonState extends State { if (memories.memories.isEmpty) { setState(() { - data = null; + file = null; type = null; }); return; @@ -67,12 +67,11 @@ class _TodayPhotoButtonState extends State { final lastMemory = memories.memories.first; - final file = await lastMemory.downloadToFile(); - final memoryData = await file.readAsBytes(); + final downloadedFile = await lastMemory.downloadToFile(); setState(() { - data = memoryData; type = lastMemory.type; + file = downloadedFile; }); } @@ -107,10 +106,10 @@ class _TodayPhotoButtonState extends State { ), child: ClipRRect( borderRadius: BorderRadius.circular(SMALL_SPACE), - child: (data == null || type == null) + child: (file == null || type == null) ? const SizedBox.shrink() : RawMemoryDisplay( - data: data!, + file: file!, type: type!, ), ), diff --git a/lib/screens/timeline_screen/memory_view.dart b/lib/screens/timeline_screen/memory_view.dart index d205e2f..1273fb6 100644 --- a/lib/screens/timeline_screen/memory_view.dart +++ b/lib/screens/timeline_screen/memory_view.dart @@ -1,5 +1,5 @@ import 'dart:async'; -import 'dart:typed_data'; +import 'dart:io'; import 'dart:ui'; import 'package:flutter/material.dart'; @@ -39,7 +39,7 @@ class MemoryView extends StatefulWidget { class _MemoryViewState extends State { MemoryFetchStatus status = MemoryFetchStatus.downloading; - Uint8List? data; + File? file; Timer? _nextMemoryTimer; @override @@ -64,17 +64,15 @@ class _MemoryViewState extends State { }); try { - final file = await widget.memory.downloadToFile(); + final downloadedFile = await widget.memory.downloadToFile(); if (!mounted) { return; } - final fileData = await file.readAsBytes(); - setState(() { status = MemoryFetchStatus.done; - data = fileData; + file = downloadedFile; }); if (widget.onFileDownloaded != null) { @@ -128,16 +126,14 @@ class _MemoryViewState extends State { ImageFiltered( imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30), child: RawMemoryDisplay( - filename: widget.memory.filename, - data: data!, + file: file!, type: widget.memory.type, loopVideo: widget.loopVideo, fit: BoxFit.cover, ), ), RawMemoryDisplay( - filename: widget.memory.filename, - data: data!, + file: file!, type: widget.memory.type, fit: BoxFit.contain, loopVideo: widget.loopVideo, diff --git a/lib/widgets/raw_memory_display.dart b/lib/widgets/raw_memory_display.dart index a4d40e9..955a51b 100644 --- a/lib/widgets/raw_memory_display.dart +++ b/lib/widgets/raw_memory_display.dart @@ -2,27 +2,29 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:quid_faciam_hodie/enums.dart'; import 'package:video_player/video_player.dart'; class RawMemoryDisplay extends StatefulWidget { - final Uint8List data; + final File? file; + final Uint8List? data; final MemoryType type; final bool loopVideo; - final String? filename; final void Function(VideoPlayerController)? onVideoControllerInitialized; final BoxFit? fit; const RawMemoryDisplay({ Key? key, - required this.data, required this.type, this.loopVideo = false, this.fit = BoxFit.cover, - this.filename, this.onVideoControllerInitialized, - }) : super(key: key); + this.file, + this.data, + }) : assert(data != null || file != null), + assert((type == MemoryType.photo) || + (type == MemoryType.video && data != null)), + super(key: key); @override State createState() => _RawMemoryDisplayState(); @@ -40,27 +42,9 @@ class _RawMemoryDisplayState extends State { } } - Future createTempVideo() async { - final tempDirectory = await getTemporaryDirectory(); - final path = '${tempDirectory.path}/${widget.filename ?? 'video.mp4'}'; - final file = File(path); - - if (await file.exists()) { - // File already exists, so just return it - return file; - } - - // File needs to be created - await file.create(); - await file.writeAsBytes(widget.data); - - return file; - } - Future initializeVideo() async { - final file = await createTempVideo(); - - videoController = VideoPlayerController.file(file); + // `file` MUST be defined for videos. + videoController = VideoPlayerController.file(widget.file!); videoController!.initialize().then((value) { if (!mounted) { return; @@ -87,8 +71,15 @@ class _RawMemoryDisplayState extends State { Widget build(BuildContext context) { switch (widget.type) { case MemoryType.photo: - return Image.memory( - widget.data, + if (widget.data != null) { + return Image.memory( + widget.data!, + fit: widget.fit, + ); + } + + return Image.file( + widget.file!, fit: widget.fit, ); case MemoryType.video: