add proper logging
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
|
||||
class CurrentUserCubit extends Cubit<User> {
|
||||
CurrentUserCubit(super.initialState);
|
||||
}
|
||||
@@ -4,43 +4,51 @@ import 'package:flutter/material.dart';
|
||||
class LoginPageState {
|
||||
final bool isServerValidated;
|
||||
final bool isValidationInProgress;
|
||||
final bool isLoginSuccessful;
|
||||
|
||||
const LoginPageState({
|
||||
required this.isServerValidated,
|
||||
required this.isValidationInProgress,
|
||||
required this.isLoginSuccessful,
|
||||
});
|
||||
|
||||
factory LoginPageState.reset() {
|
||||
return const LoginPageState(
|
||||
isServerValidated: false,
|
||||
isValidationInProgress: false,
|
||||
isLoginSuccessful: false,
|
||||
);
|
||||
}
|
||||
|
||||
LoginPageState copyWith({
|
||||
bool? isServerValidated,
|
||||
bool? isValidationInProgress,
|
||||
bool? isLoginSuccessful,
|
||||
}) {
|
||||
return LoginPageState(
|
||||
isServerValidated: isServerValidated ?? this.isServerValidated,
|
||||
isValidationInProgress:
|
||||
isValidationInProgress ?? this.isValidationInProgress,
|
||||
isLoginSuccessful: isLoginSuccessful ?? this.isLoginSuccessful,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'LoginPageState(isServerValidated: $isServerValidated, isValidationInProgress: $isValidationInProgress)';
|
||||
'LoginPageState(isServerValidated: $isServerValidated, isValidationInProgress: $isValidationInProgress, isLoginSuccessful: $isLoginSuccessful)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant LoginPageState other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.isServerValidated == isServerValidated &&
|
||||
other.isValidationInProgress == isValidationInProgress;
|
||||
other.isValidationInProgress == isValidationInProgress &&
|
||||
other.isLoginSuccessful == isLoginSuccessful;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
isServerValidated.hashCode ^ isValidationInProgress.hashCode;
|
||||
isServerValidated.hashCode ^
|
||||
isValidationInProgress.hashCode ^
|
||||
isLoginSuccessful.hashCode;
|
||||
}
|
||||
|
||||
@@ -152,13 +152,20 @@ class _LoginPageState extends State<LoginPage>
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: appBar,
|
||||
body: SafeArea(
|
||||
child: ImAdaptiveScaffoldBody(
|
||||
primaryBody: (_) => primaryBody,
|
||||
secondaryBody: (_) => secondaryBody,
|
||||
return BlocListener<LoginPageCubit, LoginPageState>(
|
||||
listener: (_, loginState) {
|
||||
if (loginState.isLoginSuccessful) {
|
||||
context.replaceRoute(const TabControllerRoute());
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: appBar,
|
||||
body: SafeArea(
|
||||
child: ImAdaptiveScaffoldBody(
|
||||
primaryBody: (_) => primaryBody,
|
||||
secondaryBody: (_) => secondaryBody,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/user.interface.dart';
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/domain/services/login.service.dart';
|
||||
import 'package:immich_mobile/domain/store_manager.dart';
|
||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||
import 'package:immich_mobile/i18n/strings.g.dart';
|
||||
import 'package:immich_mobile/presentation/modules/common/states/server_info/server_feature_config.state.dart';
|
||||
import 'package:immich_mobile/presentation/modules/login/models/login_page.model.dart';
|
||||
import 'package:immich_mobile/service_locator.dart';
|
||||
import 'package:immich_mobile/utils/immich_auth_interceptor.dart';
|
||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
||||
import 'package:immich_mobile/utils/snackbar_manager.dart';
|
||||
import 'package:openapi/openapi.dart';
|
||||
|
||||
class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
|
||||
LoginPageCubit() : super(LoginPageState.reset());
|
||||
@@ -60,8 +65,8 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
|
||||
// Check for /.well-known/immich
|
||||
url = await loginService.resolveEndpoint(uri);
|
||||
|
||||
di<StoreManager>().put(StoreKey.serverEndpoint, url);
|
||||
ServiceLocator.registerPostValidationServices(url);
|
||||
di<IStoreRepository>().set(StoreKey.serverEndpoint, url);
|
||||
await ServiceLocator.registerPostValidationServices(url);
|
||||
|
||||
// Fetch server features
|
||||
await di<ServerFeatureConfigCubit>().getFeatures();
|
||||
@@ -76,15 +81,64 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
|
||||
required String email,
|
||||
required String password,
|
||||
}) async {
|
||||
emit(state.copyWith(isValidationInProgress: true));
|
||||
try {
|
||||
emit(state.copyWith(isValidationInProgress: true));
|
||||
final accessToken =
|
||||
await di<LoginService>().passwordLogin(email, password);
|
||||
|
||||
final url = di<StoreManager>().get(StoreKey.serverEndpoint);
|
||||
if (accessToken == null) {
|
||||
SnackbarManager.showError(t.login.error.error_login);
|
||||
return;
|
||||
}
|
||||
|
||||
await _postLogin(accessToken);
|
||||
} finally {
|
||||
emit(state.copyWith(isValidationInProgress: false));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> oAuthLogin() async {
|
||||
emit(state.copyWith(isValidationInProgress: true));
|
||||
try {
|
||||
emit(state.copyWith(isValidationInProgress: true));
|
||||
|
||||
final url = di<StoreManager>().get(StoreKey.serverEndpoint);
|
||||
final accessToken = await di<LoginService>().oAuthLogin();
|
||||
|
||||
if (accessToken == null) {
|
||||
SnackbarManager.showError(t.login.error.error_login_oauth);
|
||||
return;
|
||||
}
|
||||
|
||||
await _postLogin(accessToken);
|
||||
} finally {
|
||||
emit(state.copyWith(isValidationInProgress: false));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _postLogin(String accessToken) async {
|
||||
await di<IStoreRepository>().set(StoreKey.accessToken, accessToken);
|
||||
|
||||
/// Set token to interceptor
|
||||
final interceptor = di<Openapi>()
|
||||
.dio
|
||||
.interceptors
|
||||
.firstWhereOrNull((i) => i is ImmichAuthInterceptor)
|
||||
as ImmichAuthInterceptor?;
|
||||
interceptor?.setAccessToken(accessToken);
|
||||
|
||||
final user = await di<UserService>().getMyUser();
|
||||
if (user == null) {
|
||||
SnackbarManager.showError(t.login.error.error_login);
|
||||
return;
|
||||
}
|
||||
|
||||
// Register user
|
||||
ServiceLocator.registerCurrentUser(user);
|
||||
await di<IUserRepository>().insertUser(user);
|
||||
|
||||
emit(state.copyWith(
|
||||
isValidationInProgress: false,
|
||||
isServerValidated: true,
|
||||
));
|
||||
}
|
||||
|
||||
void resetServerValidation() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:immich_mobile/domain/models/server-info/server_feature_config.model.dart';
|
||||
import 'package:immich_mobile/i18n/strings.g.dart';
|
||||
import 'package:immich_mobile/presentation/components/common/gap.widget.dart';
|
||||
import 'package:immich_mobile/presentation/components/common/loading_indaticator.widget.dart';
|
||||
import 'package:immich_mobile/presentation/components/common/loading_indicator.widget.dart';
|
||||
import 'package:immich_mobile/presentation/components/input/filled_button.widget.dart';
|
||||
import 'package:immich_mobile/presentation/components/input/password_form_field.widget.dart';
|
||||
import 'package:immich_mobile/presentation/components/input/text_button.widget.dart';
|
||||
@@ -132,6 +132,7 @@ class _CredentialsPageState extends State<_CredentialsPage> {
|
||||
children: [
|
||||
if (state.features.hasPasswordLogin) ...[
|
||||
ImTextFormField(
|
||||
controller: widget.emailController,
|
||||
label: context.t.login.label.email,
|
||||
isDisabled: isValidationInProgress,
|
||||
textInputAction: TextInputAction.next,
|
||||
@@ -139,6 +140,7 @@ class _CredentialsPageState extends State<_CredentialsPage> {
|
||||
),
|
||||
const SizedGap.mh(),
|
||||
ImPasswordFormField(
|
||||
controller: widget.passwordController,
|
||||
label: context.t.login.label.password,
|
||||
focusNode: passwordFocusNode,
|
||||
isDisabled: isValidationInProgress,
|
||||
@@ -148,11 +150,12 @@ class _CredentialsPageState extends State<_CredentialsPage> {
|
||||
ImFilledButton(
|
||||
label: context.t.login.label.login_button,
|
||||
icon: Symbols.login_rounded,
|
||||
onPressed: () =>
|
||||
context.read<LoginPageCubit>().passwordLogin(
|
||||
email: widget.emailController.text,
|
||||
password: widget.passwordController.text,
|
||||
),
|
||||
onPressed: () => unawaited(
|
||||
context.read<LoginPageCubit>().passwordLogin(
|
||||
email: widget.emailController.text,
|
||||
password: widget.passwordController.text,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Divider when both password and oAuth login is enabled
|
||||
if (state.features.hasOAuthLogin) const Divider(),
|
||||
|
||||
Reference in New Issue
Block a user