Login: Fixed two instance of start backup screen (#1455)
This commit is contained in:
commit
9b18e81c69
6 changed files with 126 additions and 102 deletions
|
@ -13,6 +13,7 @@ import "package:photos/core/errors.dart";
|
|||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/core/network/network.dart';
|
||||
import 'package:photos/db/public_keys_db.dart';
|
||||
import "package:photos/events/account_configured_event.dart";
|
||||
import 'package:photos/events/two_factor_status_change_event.dart';
|
||||
import 'package:photos/events/user_details_changed_event.dart';
|
||||
import "package:photos/generated/l10n.dart";
|
||||
|
@ -340,9 +341,10 @@ class UserService {
|
|||
} else {
|
||||
page = const PasswordReentryPage();
|
||||
}
|
||||
|
||||
} else {
|
||||
page = const PasswordEntryPage(mode: PasswordEntryMode.set,);
|
||||
page = const PasswordEntryPage(
|
||||
mode: PasswordEntryMode.set,
|
||||
);
|
||||
}
|
||||
}
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
|
@ -529,7 +531,7 @@ class UserService {
|
|||
final clientM = client.calculateClientEvidenceMessage();
|
||||
// ignore: unused_local_variable
|
||||
late Response srpCompleteResponse;
|
||||
if(setKeysRequest == null) {
|
||||
if (setKeysRequest == null) {
|
||||
srpCompleteResponse = await _enteDio.post(
|
||||
"/users/srp/complete",
|
||||
data: {
|
||||
|
@ -550,8 +552,8 @@ class UserService {
|
|||
} else {
|
||||
throw Exception("register-srp action failed");
|
||||
}
|
||||
} catch (e,s) {
|
||||
_logger.severe("failed to register srp" ,e,s);
|
||||
} catch (e, s) {
|
||||
_logger.severe("failed to register srp", e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
@ -644,14 +646,19 @@ class UserService {
|
|||
}
|
||||
}
|
||||
await dialog.hide();
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return page;
|
||||
},
|
||||
),
|
||||
(route) => route.isFirst,
|
||||
);
|
||||
if (page is HomeWidget) {
|
||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||
Bus.instance.fire(AccountConfiguredEvent());
|
||||
} else {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return page;
|
||||
},
|
||||
),
|
||||
(route) => route.isFirst,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// should never reach here
|
||||
throw Exception("unexpected response during email verification");
|
||||
|
@ -693,9 +700,10 @@ class UserService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> updateKeyAttributes(KeyAttributes keyAttributes, Uint8List
|
||||
loginKey,)
|
||||
async {
|
||||
Future<void> updateKeyAttributes(
|
||||
KeyAttributes keyAttributes,
|
||||
Uint8List loginKey,
|
||||
) async {
|
||||
try {
|
||||
final setKeyRequest = SetKeysRequest(
|
||||
kekSalt: keyAttributes.kekSalt,
|
||||
|
@ -1125,13 +1133,14 @@ class UserService {
|
|||
bool hasEnabledTwoFactor() {
|
||||
return _preferences.getBool(keyHasEnabledTwoFactor) ?? false;
|
||||
}
|
||||
|
||||
bool hasEmailMFAEnabled() {
|
||||
final UserDetails? profile = getCachedUserDetails();
|
||||
if (profile != null && profile.profileData != null) {
|
||||
return profile.profileData!.isEmailMFAEnabled;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateEmailMFA(bool isEnabled) async {
|
||||
try {
|
||||
|
@ -1148,7 +1157,7 @@ class UserService {
|
|||
await _preferences.setString(keyUserDetails, profile.toJson());
|
||||
}
|
||||
} catch (e) {
|
||||
_logger.severe("Failed to update email mfa",e);
|
||||
_logger.severe("Failed to update email mfa", e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:email_validator/email_validator.dart';
|
||||
import "package:flutter/foundation.dart";
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:logging/logging.dart";
|
||||
import 'package:photos/core/configuration.dart';
|
||||
|
@ -28,7 +29,11 @@ class _LoginPageState extends State<LoginPage> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
_email = _config.getEmail();
|
||||
if ((_config.getEmail() ?? '').isNotEmpty) {
|
||||
updateEmail(_config.getEmail()!);
|
||||
} else if (kDebugMode) {
|
||||
updateEmail(const String.fromEnvironment("email"));
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -143,19 +148,12 @@ class _LoginPageState extends State<LoginPage> {
|
|||
),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_email = value.trim();
|
||||
_emailIsValid = EmailValidator.validate(_email!);
|
||||
if (_emailIsValid) {
|
||||
_emailInputFieldColor =
|
||||
const Color.fromRGBO(45, 194, 98, 0.2);
|
||||
} else {
|
||||
_emailInputFieldColor = null;
|
||||
}
|
||||
updateEmail(value);
|
||||
});
|
||||
},
|
||||
autocorrect: false,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
//initialValue: _email,
|
||||
initialValue: _email,
|
||||
autofocus: true,
|
||||
),
|
||||
),
|
||||
|
@ -179,31 +177,33 @@ class _LoginPageState extends State<LoginPage> {
|
|||
.copyWith(fontSize: 12),
|
||||
tags: {
|
||||
'u-terms': StyledTextActionTag(
|
||||
(String? text, Map<String?, String?> attrs) => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return WebPage(
|
||||
S.of(context).termsOfServicesTitle,
|
||||
"https://ente.io/terms",
|
||||
);
|
||||
},
|
||||
),
|
||||
(String? text, Map<String?, String?> attrs) =>
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return WebPage(
|
||||
S.of(context).termsOfServicesTitle,
|
||||
"https://ente.io/terms",
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
'u-policy': StyledTextActionTag(
|
||||
(String? text, Map<String?, String?> attrs) => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return WebPage(
|
||||
S.of(context).privacyPolicyTitle,
|
||||
"https://ente.io/privacy",
|
||||
);
|
||||
},
|
||||
),
|
||||
(String? text, Map<String?, String?> attrs) =>
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return WebPage(
|
||||
S.of(context).privacyPolicyTitle,
|
||||
"https://ente.io/privacy",
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
|
@ -226,4 +226,14 @@ class _LoginPageState extends State<LoginPage> {
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
void updateEmail(String value) {
|
||||
_email = value.trim();
|
||||
_emailIsValid = EmailValidator.validate(_email!);
|
||||
if (_emailIsValid) {
|
||||
_emailInputFieldColor = const Color.fromRGBO(45, 194, 98, 0.2);
|
||||
} else {
|
||||
_emailInputFieldColor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
import "package:flutter/foundation.dart";
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import "package:photos/generated/l10n.dart";
|
||||
|
@ -15,14 +15,17 @@ import "package:photos/utils/dialog_util.dart";
|
|||
// volatile password.
|
||||
class LoginPasswordVerificationPage extends StatefulWidget {
|
||||
final SrpAttributes srpAttributes;
|
||||
const LoginPasswordVerificationPage({Key? key, required this.srpAttributes}) : super(key: key);
|
||||
|
||||
const LoginPasswordVerificationPage({Key? key, required this.srpAttributes})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<LoginPasswordVerificationPage> createState() => _LoginPasswordVerificationPageState();
|
||||
State<LoginPasswordVerificationPage> createState() =>
|
||||
_LoginPasswordVerificationPageState();
|
||||
}
|
||||
|
||||
class _LoginPasswordVerificationPageState extends
|
||||
State<LoginPasswordVerificationPage> {
|
||||
class _LoginPasswordVerificationPageState
|
||||
extends State<LoginPasswordVerificationPage> {
|
||||
final _passwordController = TextEditingController();
|
||||
final FocusNode _passwordFocusNode = FocusNode();
|
||||
String? email;
|
||||
|
@ -33,6 +36,9 @@ State<LoginPasswordVerificationPage> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
email = Configuration.instance.getEmail();
|
||||
if (kDebugMode) {
|
||||
_passwordController.text = const String.fromEnvironment("password");
|
||||
}
|
||||
_passwordFocusNode.addListener(() {
|
||||
setState(() {
|
||||
_passwordInFocus = _passwordFocusNode.hasFocus;
|
||||
|
@ -79,9 +85,11 @@ State<LoginPasswordVerificationPage> {
|
|||
buttonText: S.of(context).logInLabel,
|
||||
onPressedFunction: () async {
|
||||
FocusScope.of(context).unfocus();
|
||||
await UserService.instance.verifyEmailViaPassword(context, widget
|
||||
.srpAttributes,
|
||||
_passwordController.text,);
|
||||
await UserService.instance.verifyEmailViaPassword(
|
||||
context,
|
||||
widget.srpAttributes,
|
||||
_passwordController.text,
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButtonLocation: fabLocation(),
|
||||
|
@ -97,17 +105,22 @@ State<LoginPasswordVerificationPage> {
|
|||
child: ListView(
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 30, left: 20, right: 20),
|
||||
padding: const EdgeInsets.only(top: 30, left: 20, right: 20),
|
||||
child: Text(
|
||||
S.of(context).enterPassword,
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 30, left: 22, right:
|
||||
20,),
|
||||
child: Text(email ?? '', style: getEnteTextTheme(context).smallMuted,),
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 30,
|
||||
left: 22,
|
||||
right: 20,
|
||||
),
|
||||
child: Text(
|
||||
email ?? '',
|
||||
style: getEnteTextTheme(context).smallMuted,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
// hidden textForm for suggesting auto-fill service for saving
|
||||
|
@ -138,19 +151,19 @@ State<LoginPasswordVerificationPage> {
|
|||
),
|
||||
suffixIcon: _passwordInFocus
|
||||
? IconButton(
|
||||
icon: Icon(
|
||||
_passwordVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_passwordVisible = !_passwordVisible;
|
||||
});
|
||||
},
|
||||
)
|
||||
icon: Icon(
|
||||
_passwordVisible
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_passwordVisible = !_passwordVisible;
|
||||
});
|
||||
},
|
||||
)
|
||||
: null,
|
||||
),
|
||||
style: const TextStyle(
|
||||
|
@ -181,9 +194,11 @@ State<LoginPasswordVerificationPage> {
|
|||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () async {
|
||||
await UserService.instance
|
||||
.sendOtt(context, email!,
|
||||
isResetPasswordScreen: true,);
|
||||
await UserService.instance.sendOtt(
|
||||
context,
|
||||
email!,
|
||||
isResetPasswordScreen: true,
|
||||
);
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
|
@ -192,9 +207,9 @@ State<LoginPasswordVerificationPage> {
|
|||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -218,9 +233,9 @@ State<LoginPasswordVerificationPage> {
|
|||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -234,4 +249,4 @@ State<LoginPasswordVerificationPage> {
|
|||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,6 @@ import 'package:flutter/widgets.dart' hide PageView;
|
|||
///
|
||||
/// Based on commit 3932ffb1cd5dfa0c3891c60977ee4f9cd70ade66 on channel dev
|
||||
|
||||
// Having this global (mutable) page controller is a bit of a hack. We need it
|
||||
// to plumb in the factory for _PagePosition, but it will end up accumulating
|
||||
// a large list of scroll positions. As long as you don't try to actually
|
||||
// control the scroll positions, everything should be fine.
|
||||
final PageController _defaultPageController = PageController();
|
||||
const PageScrollPhysics _kPagePhysics = PageScrollPhysics();
|
||||
|
||||
/// A scrollable list that works page by page.
|
||||
|
@ -50,15 +45,14 @@ class ExtentsPageView extends StatefulWidget {
|
|||
Key? key,
|
||||
this.scrollDirection = Axis.horizontal,
|
||||
this.reverse = false,
|
||||
PageController? controller,
|
||||
required this.controller,
|
||||
this.physics,
|
||||
this.pageSnapping = true,
|
||||
this.onPageChanged,
|
||||
List<Widget> children = const <Widget>[],
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
this.openDrawer,
|
||||
}) : controller = controller ?? _defaultPageController,
|
||||
childrenDelegate = SliverChildListDelegate(children),
|
||||
}) : childrenDelegate = SliverChildListDelegate(children),
|
||||
extents = children.length,
|
||||
super(key: key);
|
||||
|
||||
|
@ -82,7 +76,7 @@ class ExtentsPageView extends StatefulWidget {
|
|||
Key? key,
|
||||
this.scrollDirection = Axis.horizontal,
|
||||
this.reverse = false,
|
||||
PageController? controller,
|
||||
required this.controller,
|
||||
this.physics,
|
||||
this.pageSnapping = true,
|
||||
this.onPageChanged,
|
||||
|
@ -90,8 +84,7 @@ class ExtentsPageView extends StatefulWidget {
|
|||
int? itemCount,
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
this.openDrawer,
|
||||
}) : controller = controller ?? _defaultPageController,
|
||||
childrenDelegate =
|
||||
}) : childrenDelegate =
|
||||
SliverChildBuilderDelegate(itemBuilder, childCount: itemCount),
|
||||
extents = 0,
|
||||
super(key: key);
|
||||
|
@ -101,7 +94,7 @@ class ExtentsPageView extends StatefulWidget {
|
|||
this.extents = 1,
|
||||
this.scrollDirection = Axis.horizontal,
|
||||
this.reverse = false,
|
||||
PageController? controller,
|
||||
required this.controller,
|
||||
this.physics,
|
||||
this.pageSnapping = true,
|
||||
this.onPageChanged,
|
||||
|
@ -109,8 +102,7 @@ class ExtentsPageView extends StatefulWidget {
|
|||
int? itemCount,
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
this.openDrawer,
|
||||
}) : controller = controller ?? _defaultPageController,
|
||||
childrenDelegate = SliverChildBuilderDelegate(
|
||||
}) : childrenDelegate = SliverChildBuilderDelegate(
|
||||
itemBuilder,
|
||||
childCount: itemCount,
|
||||
addAutomaticKeepAlives: false,
|
||||
|
@ -202,7 +194,7 @@ class ExtentsPageView extends StatefulWidget {
|
|||
Key? key,
|
||||
this.scrollDirection = Axis.horizontal,
|
||||
this.reverse = false,
|
||||
PageController? controller,
|
||||
required this.controller,
|
||||
this.physics,
|
||||
this.pageSnapping = true,
|
||||
this.onPageChanged,
|
||||
|
@ -210,7 +202,6 @@ class ExtentsPageView extends StatefulWidget {
|
|||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
this.openDrawer,
|
||||
}) : extents = 0,
|
||||
controller = controller ?? _defaultPageController,
|
||||
super(key: key);
|
||||
|
||||
/// The number of pages to build off screen.
|
||||
|
@ -297,7 +288,6 @@ class _PageViewState extends State<ExtentsPageView> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_pageController ??= PageController(initialPage: _index);
|
||||
final file = widget.memories[_index].file;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
|
@ -292,7 +291,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
|
|||
debugPrint(
|
||||
"FullScreenbuildSwiper: $_index and total ${widget.memories.length}",
|
||||
);
|
||||
_pageController = PageController(initialPage: _index);
|
||||
_pageController ??= PageController(initialPage: _index);
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTapDown: (TapDownDetails details) {
|
||||
|
@ -343,7 +342,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
|
|||
);
|
||||
},
|
||||
itemCount: widget.memories.length,
|
||||
controller: _pageController,
|
||||
controller: _pageController!,
|
||||
onPageChanged: (index) async {
|
||||
unawaited(
|
||||
MemoriesService.instance.markMemoryAsSeen(widget.memories[index]),
|
||||
|
|
|
@ -263,6 +263,7 @@ class _HomeWidgetState extends State<HomeWidget> {
|
|||
_accountConfiguredEvent.cancel();
|
||||
_intentDataStreamSubscription?.cancel();
|
||||
_collectionUpdatedEvent.cancel();
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue