mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-18 23:35:25 +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.",
|
"loginScreenHelpText": "Melde dich an. Wenn du noch keinen Account besitzt, erstellen wir automatisch einen für dich.",
|
||||||
"loginScreenFormEmailLabel": "E-Mail",
|
"loginScreenFormEmailLabel": "E-Mail",
|
||||||
"loginScreenFormPasswordLabel": "Passwort",
|
"loginScreenFormPasswordLabel": "Passwort",
|
||||||
"loginScreenFormSubmitButton": "Anmelden",
|
"loginScreenFormLoginButton": "Anmelden",
|
||||||
|
"loginScreenFormSignUpButton": "Registrieren",
|
||||||
"loginScreenLoginFailed": "E-Mail oder Passwort inkorrekt",
|
"loginScreenLoginFailed": "E-Mail oder Passwort inkorrekt",
|
||||||
"loginScreenSignUpDialogTitle": "Registrieren",
|
"loginScreenSignUpFailed": "Registrierung fehlgeschlagen. Hast du eventuell schon einen Account?",
|
||||||
"loginScreenSignUpDialogExplanation": "Wir haben deinen Account nicht gefunden. Möchtest du dich jetzt registrieren?",
|
|
||||||
"loginScreenSignUpDialogAffirmationLabel": "Jetzt registrieren",
|
|
||||||
|
|
||||||
|
|
||||||
"grantPermissionScreenTitle": "Berechtigungen erteilen",
|
"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.",
|
"loginScreenHelpText": "Sign in to your account. If you do not have one already, we will automatically set up one for you.",
|
||||||
"loginScreenFormEmailLabel": "Email",
|
"loginScreenFormEmailLabel": "Email",
|
||||||
"loginScreenFormPasswordLabel": "Password",
|
"loginScreenFormPasswordLabel": "Password",
|
||||||
"loginScreenFormSubmitButton": "Login",
|
"loginScreenFormLoginButton": "Login",
|
||||||
|
"loginScreenFormSignUpButton": "Sign up",
|
||||||
"loginScreenLoginFailed": "Email or password incorrect",
|
"loginScreenLoginFailed": "Email or password incorrect",
|
||||||
"loginScreenSignUpDialogTitle": "Sign up",
|
"loginScreenSignUpFailed": "Registration failed. Maybe you already have an account?",
|
||||||
"loginScreenSignUpDialogExplanation": "We didn't find your account. Do you want to sign up now?",
|
|
||||||
"loginScreenSignUpDialogAffirmationLabel": "Sign me up now",
|
|
||||||
|
|
||||||
|
|
||||||
"grantPermissionScreenTitle": "Grant Permissions",
|
"grantPermissionScreenTitle": "Grant Permissions",
|
||||||
|
@ -46,20 +46,22 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _signUp() async {
|
Future<void> _onAuthenticated() async {
|
||||||
final response = await supabase.auth.signUp(
|
if (!mounted) {
|
||||||
emailController.text.trim(),
|
return;
|
||||||
passwordController.text,
|
|
||||||
);
|
|
||||||
|
|
||||||
final error = response.error;
|
|
||||||
|
|
||||||
if (error != null) {
|
|
||||||
throw Exception(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
final response = await supabase.auth.signIn(
|
||||||
email: emailController.text.trim(),
|
email: emailController.text.trim(),
|
||||||
password: passwordController.text,
|
password: passwordController.text,
|
||||||
@ -67,63 +69,46 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
|||||||
|
|
||||||
final error = response.error;
|
final error = response.error;
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
throw Exception(error);
|
context.showLongErrorSnackBar(
|
||||||
}
|
message: localizations.loginScreenLoginFailed,
|
||||||
}
|
|
||||||
|
|
||||||
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(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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
|
@override
|
||||||
@ -148,16 +133,18 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
|||||||
cupertino: (data) => data.textTheme.navLargeTitleTextStyle,
|
cupertino: (data) => data.textTheme.navLargeTitleTextStyle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: LARGE_SPACE),
|
const Flexible(child: SizedBox(height: LARGE_SPACE)),
|
||||||
Text(
|
Flexible(
|
||||||
localizations.loginScreenHelpText,
|
child: Text(
|
||||||
style: platformThemeData(
|
localizations.loginScreenHelpText,
|
||||||
context,
|
style: platformThemeData(
|
||||||
material: (data) => data.textTheme.bodyText1,
|
context,
|
||||||
cupertino: (data) => data.textTheme.textStyle,
|
material: (data) => data.textTheme.bodyText1,
|
||||||
|
cupertino: (data) => data.textTheme.textStyle,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
const Flexible(child: SizedBox(height: MEDIUM_SPACE)),
|
||||||
PlatformTextField(
|
PlatformTextField(
|
||||||
controller: emailController,
|
controller: emailController,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -191,13 +178,25 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
|||||||
),
|
),
|
||||||
onSubmitted: (value) => callWithLoading(signIn),
|
onSubmitted: (value) => callWithLoading(signIn),
|
||||||
),
|
),
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
const Flexible(child: SizedBox(height: MEDIUM_SPACE)),
|
||||||
PlatformElevatedButton(
|
Row(
|
||||||
onPressed: isLoading ? null : () => callWithLoading(signIn),
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
child: IconButtonChild(
|
children: <Widget>[
|
||||||
icon: Icon(context.platformIcons.forward),
|
PlatformElevatedButton(
|
||||||
label: Text(localizations.loginScreenFormSubmitButton),
|
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:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -25,7 +25,7 @@ class TodayPhotoButton extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
||||||
Uint8List? data;
|
File? file;
|
||||||
MemoryType? type;
|
MemoryType? type;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -59,7 +59,7 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
|||||||
|
|
||||||
if (memories.memories.isEmpty) {
|
if (memories.memories.isEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
data = null;
|
file = null;
|
||||||
type = null;
|
type = null;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -67,12 +67,11 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
|||||||
|
|
||||||
final lastMemory = memories.memories.first;
|
final lastMemory = memories.memories.first;
|
||||||
|
|
||||||
final file = await lastMemory.downloadToFile();
|
final downloadedFile = await lastMemory.downloadToFile();
|
||||||
final memoryData = await file.readAsBytes();
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
data = memoryData;
|
|
||||||
type = lastMemory.type;
|
type = lastMemory.type;
|
||||||
|
file = downloadedFile;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,10 +106,10 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
|||||||
),
|
),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(SMALL_SPACE),
|
borderRadius: BorderRadius.circular(SMALL_SPACE),
|
||||||
child: (data == null || type == null)
|
child: (file == null || type == null)
|
||||||
? const SizedBox.shrink()
|
? const SizedBox.shrink()
|
||||||
: RawMemoryDisplay(
|
: RawMemoryDisplay(
|
||||||
data: data!,
|
file: file!,
|
||||||
type: type!,
|
type: type!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:io';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -39,7 +39,7 @@ class MemoryView extends StatefulWidget {
|
|||||||
|
|
||||||
class _MemoryViewState extends State<MemoryView> {
|
class _MemoryViewState extends State<MemoryView> {
|
||||||
MemoryFetchStatus status = MemoryFetchStatus.downloading;
|
MemoryFetchStatus status = MemoryFetchStatus.downloading;
|
||||||
Uint8List? data;
|
File? file;
|
||||||
Timer? _nextMemoryTimer;
|
Timer? _nextMemoryTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -64,17 +64,15 @@ class _MemoryViewState extends State<MemoryView> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final file = await widget.memory.downloadToFile();
|
final downloadedFile = await widget.memory.downloadToFile();
|
||||||
|
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final fileData = await file.readAsBytes();
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
status = MemoryFetchStatus.done;
|
status = MemoryFetchStatus.done;
|
||||||
data = fileData;
|
file = downloadedFile;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (widget.onFileDownloaded != null) {
|
if (widget.onFileDownloaded != null) {
|
||||||
@ -128,16 +126,14 @@ class _MemoryViewState extends State<MemoryView> {
|
|||||||
ImageFiltered(
|
ImageFiltered(
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
|
imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
|
||||||
child: RawMemoryDisplay(
|
child: RawMemoryDisplay(
|
||||||
filename: widget.memory.filename,
|
file: file!,
|
||||||
data: data!,
|
|
||||||
type: widget.memory.type,
|
type: widget.memory.type,
|
||||||
loopVideo: widget.loopVideo,
|
loopVideo: widget.loopVideo,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
RawMemoryDisplay(
|
RawMemoryDisplay(
|
||||||
filename: widget.memory.filename,
|
file: file!,
|
||||||
data: data!,
|
|
||||||
type: widget.memory.type,
|
type: widget.memory.type,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
loopVideo: widget.loopVideo,
|
loopVideo: widget.loopVideo,
|
||||||
|
@ -2,27 +2,29 @@ import 'dart:io';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:quid_faciam_hodie/enums.dart';
|
import 'package:quid_faciam_hodie/enums.dart';
|
||||||
import 'package:video_player/video_player.dart';
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
class RawMemoryDisplay extends StatefulWidget {
|
class RawMemoryDisplay extends StatefulWidget {
|
||||||
final Uint8List data;
|
final File? file;
|
||||||
|
final Uint8List? data;
|
||||||
final MemoryType type;
|
final MemoryType type;
|
||||||
final bool loopVideo;
|
final bool loopVideo;
|
||||||
final String? filename;
|
|
||||||
final void Function(VideoPlayerController)? onVideoControllerInitialized;
|
final void Function(VideoPlayerController)? onVideoControllerInitialized;
|
||||||
final BoxFit? fit;
|
final BoxFit? fit;
|
||||||
|
|
||||||
const RawMemoryDisplay({
|
const RawMemoryDisplay({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.data,
|
|
||||||
required this.type,
|
required this.type,
|
||||||
this.loopVideo = false,
|
this.loopVideo = false,
|
||||||
this.fit = BoxFit.cover,
|
this.fit = BoxFit.cover,
|
||||||
this.filename,
|
|
||||||
this.onVideoControllerInitialized,
|
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
|
@override
|
||||||
State<RawMemoryDisplay> createState() => _RawMemoryDisplayState();
|
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 {
|
Future<void> initializeVideo() async {
|
||||||
final file = await createTempVideo();
|
// `file` MUST be defined for videos.
|
||||||
|
videoController = VideoPlayerController.file(widget.file!);
|
||||||
videoController = VideoPlayerController.file(file);
|
|
||||||
videoController!.initialize().then((value) {
|
videoController!.initialize().then((value) {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
@ -87,8 +71,15 @@ class _RawMemoryDisplayState extends State<RawMemoryDisplay> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
switch (widget.type) {
|
switch (widget.type) {
|
||||||
case MemoryType.photo:
|
case MemoryType.photo:
|
||||||
return Image.memory(
|
if (widget.data != null) {
|
||||||
widget.data,
|
return Image.memory(
|
||||||
|
widget.data!,
|
||||||
|
fit: widget.fit,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Image.file(
|
||||||
|
widget.file!,
|
||||||
fit: widget.fit,
|
fit: widget.fit,
|
||||||
);
|
);
|
||||||
case MemoryType.video:
|
case MemoryType.video:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user