mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-18 15:25:27 +02:00
improved login screen; improvements & bugfixes
This commit is contained in:
parent
7ba7652917
commit
2e90e6343c
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -46,20 +46,22 @@ 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> _onAuthenticated() async {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const ServerLoadingScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _signIn() async {
|
||||
Future<void> 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<LoginScreen> with Loadable {
|
||||
|
||||
final error = response.error;
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const ServerLoadingScreen(),
|
||||
),
|
||||
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,16 +133,18 @@ class _LoginScreenState extends AuthState<LoginScreen> 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<LoginScreen> 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: <Widget>[
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -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!,
|
||||
),
|
||||
),
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user