1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 06:31:58 +00:00

fix(mobile): fix logout timeout (#14104)

* fix(mobile): add timeout to logout

* chore(mobile): refactor timeout durations

* feat(mobile): add loading state to logout button

* chore(mobile): format authentication.provider.dart

* chore: format

* chore: revert settings.json change

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
John Stef 2024-11-13 19:27:49 +02:00 committed by GitHub
parent c58bd307ce
commit de993289ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 11 deletions

View file

@ -41,6 +41,8 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
_ref; _ref;
final _log = Logger("AuthenticationNotifier"); final _log = Logger("AuthenticationNotifier");
static const Duration _timeoutDuration = Duration(seconds: 7);
Future<bool> login( Future<bool> login(
String email, String email,
String password, String password,
@ -102,12 +104,15 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
await _apiService.authenticationApi await _apiService.authenticationApi
.logout() .logout()
.timeout(_timeoutDuration)
.then((_) => log.info("Logout was successful for $userEmail")) .then((_) => log.info("Logout was successful for $userEmail"))
.onError( .onError(
(error, stackTrace) => (error, stackTrace) =>
log.severe("Logout failed for $userEmail", error, stackTrace), log.severe("Logout failed for $userEmail", error, stackTrace),
); );
} catch (e, stack) {
log.severe('Logout failed', e, stack);
} finally {
await Future.wait([ await Future.wait([
clearAssetsAndAlbums(_db), clearAssetsAndAlbums(_db),
Store.delete(StoreKey.currentUser), Store.delete(StoreKey.currentUser),
@ -125,8 +130,6 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
shouldChangePassword: false, shouldChangePassword: false,
isAuthenticated: false, isAuthenticated: false,
); );
} catch (e, stack) {
log.severe('Logout failed', e, stack);
} }
} }
@ -168,10 +171,8 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
UserPreferencesResponseDto? userPreferences; UserPreferencesResponseDto? userPreferences;
try { try {
final responses = await Future.wait([ final responses = await Future.wait([
_apiService.usersApi.getMyUser().timeout(const Duration(seconds: 7)), _apiService.usersApi.getMyUser().timeout(_timeoutDuration),
_apiService.usersApi _apiService.usersApi.getMyPreferences().timeout(_timeoutDuration),
.getMyPreferences()
.timeout(const Duration(seconds: 7)),
]); ]);
userResponse = responses[0] as UserAdminResponseDto; userResponse = responses[0] as UserAdminResponseDto;
userPreferences = responses[1] as UserPreferencesResponseDto; userPreferences = responses[1] as UserPreferencesResponseDto;

View file

@ -28,6 +28,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
bool isHorizontal = !context.isMobile; bool isHorizontal = !context.isMobile;
final horizontalPadding = isHorizontal ? 100.0 : 20.0; final horizontalPadding = isHorizontal ? 100.0 : 20.0;
final user = ref.watch(currentUserProvider); final user = ref.watch(currentUserProvider);
final isLoggingOut = useState(false);
useEffect( useEffect(
() { () {
@ -63,11 +64,16 @@ class ImmichAppBarDialog extends HookConsumerWidget {
); );
} }
buildActionButton(IconData icon, String text, Function() onTap) { buildActionButton(
IconData icon,
String text,
Function() onTap, {
Widget? trailing,
}) {
return ListTile( return ListTile(
dense: true, dense: true,
visualDensity: VisualDensity.standard, visualDensity: VisualDensity.standard,
contentPadding: const EdgeInsets.only(left: 30), contentPadding: const EdgeInsets.only(left: 30, right: 30),
minLeadingWidth: 40, minLeadingWidth: 40,
leading: SizedBox( leading: SizedBox(
child: Icon( child: Icon(
@ -83,6 +89,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
), ),
).tr(), ).tr(),
onTap: onTap, onTap: onTap,
trailing: trailing,
); );
} }
@ -107,6 +114,10 @@ class ImmichAppBarDialog extends HookConsumerWidget {
Icons.logout_rounded, Icons.logout_rounded,
"profile_drawer_sign_out", "profile_drawer_sign_out",
() async { () async {
if (isLoggingOut.value) {
return;
}
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext ctx) { builder: (BuildContext ctx) {
@ -115,7 +126,11 @@ class ImmichAppBarDialog extends HookConsumerWidget {
content: "app_bar_signout_dialog_content", content: "app_bar_signout_dialog_content",
ok: "app_bar_signout_dialog_ok", ok: "app_bar_signout_dialog_ok",
onOk: () async { onOk: () async {
await ref.read(authenticationProvider.notifier).logout(); isLoggingOut.value = true;
await ref
.read(authenticationProvider.notifier)
.logout()
.whenComplete(() => isLoggingOut.value = false);
ref.read(manualUploadProvider.notifier).cancelBackup(); ref.read(manualUploadProvider.notifier).cancelBackup();
ref.read(backupProvider.notifier).cancelBackup(); ref.read(backupProvider.notifier).cancelBackup();
@ -127,6 +142,12 @@ class ImmichAppBarDialog extends HookConsumerWidget {
}, },
); );
}, },
trailing: isLoggingOut.value
? SizedBox.square(
dimension: 20,
child: const CircularProgressIndicator(strokeWidth: 2),
)
: null,
); );
} }