improved login screen; improvements & bugfixes

This commit is contained in:
Myzel394 2022-08-25 08:39:42 +02:00
parent 7ba7652917
commit 2e90e6343c
6 changed files with 117 additions and 134 deletions

View File

@ -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",

View File

@ -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",

View File

@ -46,77 +46,11 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
super.dispose();
}
Future<void> _signUp() async {
final response = await supabase.auth.signUp(
emailController.text.trim(),
passwordController.text,
);
final error = response.error;
if (error != null) {
throw Exception(error);
}
}
Future<void> _signIn() async {
final response = await supabase.auth.signIn(
email: emailController.text.trim(),
password: passwordController.text,
);
final error = response.error;
if (error != null) {
throw Exception(error);
}
}
Future<bool> _askWhetherToSignUp() {
final localizations = AppLocalizations.of(context)!;
return showPlatformDialog(
context: context,
builder: (_) => PlatformAlertDialog(
title: Text(localizations.loginScreenSignUpDialogTitle),
content: Text(localizations.loginScreenSignUpDialogExplanation),
actions: <Widget>[
PlatformDialogAction(
child: Text(localizations.generalCancelButtonLabel),
onPressed: () => Navigator.pop(context, false),
),
PlatformDialogAction(
child: Text(localizations.loginScreenSignUpDialogAffirmationLabel),
onPressed: () => Navigator.pop(context, true),
),
],
),
) as Future<bool>;
}
Future<void> 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();
}
Future<void> _onAuthenticated() async {
if (!mounted) {
return;
}
}
}
if (mounted) {
Navigator.push(
context,
MaterialPageRoute(
@ -124,6 +58,57 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
),
);
}
Future<void> signIn() async {
final localizations = AppLocalizations.of(context)!;
final response = await supabase.auth.signIn(
email: emailController.text.trim(),
password: passwordController.text,
);
final error = response.error;
if (!mounted) {
return;
}
if (error != null) {
context.showLongErrorSnackBar(
message: localizations.loginScreenLoginFailed,
);
passwordController.clear();
return;
}
_onAuthenticated();
}
Future<void> 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,8 +133,9 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
cupertino: (data) => data.textTheme.navLargeTitleTextStyle,
),
),
const SizedBox(height: LARGE_SPACE),
Text(
const Flexible(child: SizedBox(height: LARGE_SPACE)),
Flexible(
child: Text(
localizations.loginScreenHelpText,
style: platformThemeData(
context,
@ -157,7 +143,8 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
cupertino: (data) => data.textTheme.textStyle,
),
),
const SizedBox(height: MEDIUM_SPACE),
),
const Flexible(child: SizedBox(height: MEDIUM_SPACE)),
PlatformTextField(
controller: emailController,
autofocus: true,
@ -191,14 +178,26 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
),
onSubmitted: (value) => callWithLoading(signIn),
),
const SizedBox(height: MEDIUM_SPACE),
const Flexible(child: SizedBox(height: MEDIUM_SPACE)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
PlatformElevatedButton(
onPressed: isLoading ? null : () => callWithLoading(signIn),
child: IconButtonChild(
icon: Icon(context.platformIcons.forward),
label: Text(localizations.loginScreenFormSubmitButton),
label: Text(localizations.loginScreenFormLoginButton),
),
),
PlatformTextButton(
onPressed: isLoading ? null : () => callWithLoading(signUp),
child: IconButtonChild(
icon: Icon(context.platformIcons.add),
label: Text(localizations.loginScreenFormSignUpButton),
),
),
],
),
],
),
),

View File

@ -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<TodayPhotoButton> {
Uint8List? data;
File? file;
MemoryType? type;
@override
@ -59,7 +59,7 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
if (memories.memories.isEmpty) {
setState(() {
data = null;
file = null;
type = null;
});
return;
@ -67,12 +67,11 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
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<TodayPhotoButton> {
),
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!,
),
),

View File

@ -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<MemoryView> {
MemoryFetchStatus status = MemoryFetchStatus.downloading;
Uint8List? data;
File? file;
Timer? _nextMemoryTimer;
@override
@ -64,17 +64,15 @@ class _MemoryViewState extends State<MemoryView> {
});
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<MemoryView> {
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,

View File

@ -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<RawMemoryDisplay> createState() => _RawMemoryDisplayState();
@ -40,27 +42,9 @@ class _RawMemoryDisplayState extends State<RawMemoryDisplay> {
}
}
Future<File> 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<void> 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<RawMemoryDisplay> {
Widget build(BuildContext context) {
switch (widget.type) {
case MemoryType.photo:
if (widget.data != null) {
return Image.memory(
widget.data,
widget.data!,
fit: widget.fit,
);
}
return Image.file(
widget.file!,
fit: widget.fit,
);
case MemoryType.video: