feat: Make account switching work again

This commit is contained in:
Anton Stubenbord
2023-05-12 00:37:07 +02:00
parent 2980e97747
commit 891ab8985b
7 changed files with 162 additions and 12 deletions

View File

@@ -42,7 +42,7 @@ class PaperlessApiFactoryImpl implements PaperlessApiFactory {
PaperlessUserApi createUserApi(Dio dio, {required int apiVersion}) { PaperlessUserApi createUserApi(Dio dio, {required int apiVersion}) {
if (apiVersion == 3) { if (apiVersion == 3) {
return PaperlessUserApiV3Impl(dio); return PaperlessUserApiV3Impl(dio);
} else if (apiVersion == 1 || apiVersion == 2) { } else if (apiVersion < 3) {
return PaperlessUserApiV2Impl(dio); return PaperlessUserApiV2Impl(dio);
} }
throw Exception("API $apiVersion not supported."); throw Exception("API $apiVersion not supported.");

View File

@@ -233,6 +233,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
), ),
], ],
), ),
if (apiVersion.hasMultiUserSupport)
CustomScrollView( CustomScrollView(
controller: _pagingScrollController, controller: _pagingScrollController,
slivers: [ slivers: [

View File

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
import 'package:paperless_mobile/core/exception/server_message_exception.dart'; import 'package:paperless_mobile/core/exception/server_message_exception.dart';
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart'; import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart';
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_confirm_button.dart'; import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_confirm_button.dart';
@@ -41,11 +42,13 @@ class _InboxPageState extends State<InboxPage> with DocumentPagingViewMixin<Inbo
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final canEditDocument = LocalUserAccount.current.paperlessUser
.hasPermission(PermissionAction.change, PermissionTarget.document);
return Scaffold( return Scaffold(
drawer: const AppDrawer(), drawer: const AppDrawer(),
floatingActionButton: BlocBuilder<InboxCubit, InboxState>( floatingActionButton: BlocBuilder<InboxCubit, InboxState>(
builder: (context, state) { builder: (context, state) {
if (!state.hasLoaded || state.documents.isEmpty) { if (!state.hasLoaded || state.documents.isEmpty || !canEditDocument) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return FloatingActionButton.extended( return FloatingActionButton.extended(

View File

@@ -66,6 +66,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
/// Switches to another account if it exists. /// Switches to another account if it exists.
Future<void> switchAccount(String localUserId) async { Future<void> switchAccount(String localUserId) async {
emit(const AuthenticationState.switchingAccounts());
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!; final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
if (globalSettings.currentLoggedInUser == localUserId) { if (globalSettings.currentLoggedInUser == localUserId) {
return; return;
@@ -130,12 +131,13 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
}) async { }) async {
assert(credentials.password != null && credentials.username != null); assert(credentials.password != null && credentials.username != null);
final localUserId = "${credentials.username}@$serverUrl"; final localUserId = "${credentials.username}@$serverUrl";
final sessionManager = SessionManager();
await _addUser( await _addUser(
localUserId, localUserId,
serverUrl, serverUrl,
credentials, credentials,
clientCertificate, clientCertificate,
_sessionManager, sessionManager,
); );
return localUserId; return localUserId;

View File

@@ -21,6 +21,7 @@ mixin _$AuthenticationState {
required TResult Function() unauthenticated, required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication, required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated, required TResult Function(String localUserId, int apiVersion) authenticated,
required TResult Function() switchingAccounts,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
@@ -28,6 +29,7 @@ mixin _$AuthenticationState {
TResult? Function()? unauthenticated, TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication, TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated, TResult? Function(String localUserId, int apiVersion)? authenticated,
TResult? Function()? switchingAccounts,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
@@ -35,6 +37,7 @@ mixin _$AuthenticationState {
TResult Function()? unauthenticated, TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication, TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated, TResult Function(String localUserId, int apiVersion)? authenticated,
TResult Function()? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@@ -44,6 +47,7 @@ mixin _$AuthenticationState {
required TResult Function(_RequiresLocalAuthentication value) required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication, requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated, required TResult Function(_Authenticated value) authenticated,
required TResult Function(_SwitchingAccounts value) switchingAccounts,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
@@ -52,6 +56,7 @@ mixin _$AuthenticationState {
TResult? Function(_RequiresLocalAuthentication value)? TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated, TResult? Function(_Authenticated value)? authenticated,
TResult? Function(_SwitchingAccounts value)? switchingAccounts,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
@@ -60,6 +65,7 @@ mixin _$AuthenticationState {
TResult Function(_RequiresLocalAuthentication value)? TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated, TResult Function(_Authenticated value)? authenticated,
TResult Function(_SwitchingAccounts value)? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@@ -124,6 +130,7 @@ class _$_Unauthenticated implements _Unauthenticated {
required TResult Function() unauthenticated, required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication, required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated, required TResult Function(String localUserId, int apiVersion) authenticated,
required TResult Function() switchingAccounts,
}) { }) {
return unauthenticated(); return unauthenticated();
} }
@@ -134,6 +141,7 @@ class _$_Unauthenticated implements _Unauthenticated {
TResult? Function()? unauthenticated, TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication, TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated, TResult? Function(String localUserId, int apiVersion)? authenticated,
TResult? Function()? switchingAccounts,
}) { }) {
return unauthenticated?.call(); return unauthenticated?.call();
} }
@@ -144,6 +152,7 @@ class _$_Unauthenticated implements _Unauthenticated {
TResult Function()? unauthenticated, TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication, TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated, TResult Function(String localUserId, int apiVersion)? authenticated,
TResult Function()? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (unauthenticated != null) { if (unauthenticated != null) {
@@ -159,6 +168,7 @@ class _$_Unauthenticated implements _Unauthenticated {
required TResult Function(_RequiresLocalAuthentication value) required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication, requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated, required TResult Function(_Authenticated value) authenticated,
required TResult Function(_SwitchingAccounts value) switchingAccounts,
}) { }) {
return unauthenticated(this); return unauthenticated(this);
} }
@@ -170,6 +180,7 @@ class _$_Unauthenticated implements _Unauthenticated {
TResult? Function(_RequiresLocalAuthentication value)? TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated, TResult? Function(_Authenticated value)? authenticated,
TResult? Function(_SwitchingAccounts value)? switchingAccounts,
}) { }) {
return unauthenticated?.call(this); return unauthenticated?.call(this);
} }
@@ -181,6 +192,7 @@ class _$_Unauthenticated implements _Unauthenticated {
TResult Function(_RequiresLocalAuthentication value)? TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated, TResult Function(_Authenticated value)? authenticated,
TResult Function(_SwitchingAccounts value)? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (unauthenticated != null) { if (unauthenticated != null) {
@@ -239,6 +251,7 @@ class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
required TResult Function() unauthenticated, required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication, required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated, required TResult Function(String localUserId, int apiVersion) authenticated,
required TResult Function() switchingAccounts,
}) { }) {
return requriresLocalAuthentication(); return requriresLocalAuthentication();
} }
@@ -249,6 +262,7 @@ class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
TResult? Function()? unauthenticated, TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication, TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated, TResult? Function(String localUserId, int apiVersion)? authenticated,
TResult? Function()? switchingAccounts,
}) { }) {
return requriresLocalAuthentication?.call(); return requriresLocalAuthentication?.call();
} }
@@ -259,6 +273,7 @@ class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
TResult Function()? unauthenticated, TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication, TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated, TResult Function(String localUserId, int apiVersion)? authenticated,
TResult Function()? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (requriresLocalAuthentication != null) { if (requriresLocalAuthentication != null) {
@@ -274,6 +289,7 @@ class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
required TResult Function(_RequiresLocalAuthentication value) required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication, requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated, required TResult Function(_Authenticated value) authenticated,
required TResult Function(_SwitchingAccounts value) switchingAccounts,
}) { }) {
return requriresLocalAuthentication(this); return requriresLocalAuthentication(this);
} }
@@ -285,6 +301,7 @@ class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
TResult? Function(_RequiresLocalAuthentication value)? TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated, TResult? Function(_Authenticated value)? authenticated,
TResult? Function(_SwitchingAccounts value)? switchingAccounts,
}) { }) {
return requriresLocalAuthentication?.call(this); return requriresLocalAuthentication?.call(this);
} }
@@ -296,6 +313,7 @@ class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
TResult Function(_RequiresLocalAuthentication value)? TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated, TResult Function(_Authenticated value)? authenticated,
TResult Function(_SwitchingAccounts value)? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (requriresLocalAuthentication != null) { if (requriresLocalAuthentication != null) {
@@ -386,6 +404,7 @@ class _$_Authenticated implements _Authenticated {
required TResult Function() unauthenticated, required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication, required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated, required TResult Function(String localUserId, int apiVersion) authenticated,
required TResult Function() switchingAccounts,
}) { }) {
return authenticated(localUserId, apiVersion); return authenticated(localUserId, apiVersion);
} }
@@ -396,6 +415,7 @@ class _$_Authenticated implements _Authenticated {
TResult? Function()? unauthenticated, TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication, TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated, TResult? Function(String localUserId, int apiVersion)? authenticated,
TResult? Function()? switchingAccounts,
}) { }) {
return authenticated?.call(localUserId, apiVersion); return authenticated?.call(localUserId, apiVersion);
} }
@@ -406,6 +426,7 @@ class _$_Authenticated implements _Authenticated {
TResult Function()? unauthenticated, TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication, TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated, TResult Function(String localUserId, int apiVersion)? authenticated,
TResult Function()? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (authenticated != null) { if (authenticated != null) {
@@ -421,6 +442,7 @@ class _$_Authenticated implements _Authenticated {
required TResult Function(_RequiresLocalAuthentication value) required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication, requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated, required TResult Function(_Authenticated value) authenticated,
required TResult Function(_SwitchingAccounts value) switchingAccounts,
}) { }) {
return authenticated(this); return authenticated(this);
} }
@@ -432,6 +454,7 @@ class _$_Authenticated implements _Authenticated {
TResult? Function(_RequiresLocalAuthentication value)? TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated, TResult? Function(_Authenticated value)? authenticated,
TResult? Function(_SwitchingAccounts value)? switchingAccounts,
}) { }) {
return authenticated?.call(this); return authenticated?.call(this);
} }
@@ -443,6 +466,7 @@ class _$_Authenticated implements _Authenticated {
TResult Function(_RequiresLocalAuthentication value)? TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication, requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated, TResult Function(_Authenticated value)? authenticated,
TResult Function(_SwitchingAccounts value)? switchingAccounts,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (authenticated != null) { if (authenticated != null) {
@@ -463,3 +487,120 @@ abstract class _Authenticated implements AuthenticationState {
_$$_AuthenticatedCopyWith<_$_Authenticated> get copyWith => _$$_AuthenticatedCopyWith<_$_Authenticated> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
/// @nodoc
abstract class _$$_SwitchingAccountsCopyWith<$Res> {
factory _$$_SwitchingAccountsCopyWith(_$_SwitchingAccounts value,
$Res Function(_$_SwitchingAccounts) then) =
__$$_SwitchingAccountsCopyWithImpl<$Res>;
}
/// @nodoc
class __$$_SwitchingAccountsCopyWithImpl<$Res>
extends _$AuthenticationStateCopyWithImpl<$Res, _$_SwitchingAccounts>
implements _$$_SwitchingAccountsCopyWith<$Res> {
__$$_SwitchingAccountsCopyWithImpl(
_$_SwitchingAccounts _value, $Res Function(_$_SwitchingAccounts) _then)
: super(_value, _then);
}
/// @nodoc
class _$_SwitchingAccounts implements _SwitchingAccounts {
const _$_SwitchingAccounts();
@override
String toString() {
return 'AuthenticationState.switchingAccounts()';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$_SwitchingAccounts);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated,
required TResult Function() switchingAccounts,
}) {
return switchingAccounts();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated,
TResult? Function()? switchingAccounts,
}) {
return switchingAccounts?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated,
TResult Function()? switchingAccounts,
required TResult orElse(),
}) {
if (switchingAccounts != null) {
return switchingAccounts();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Unauthenticated value) unauthenticated,
required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated,
required TResult Function(_SwitchingAccounts value) switchingAccounts,
}) {
return switchingAccounts(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Unauthenticated value)? unauthenticated,
TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated,
TResult? Function(_SwitchingAccounts value)? switchingAccounts,
}) {
return switchingAccounts?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Unauthenticated value)? unauthenticated,
TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated,
TResult Function(_SwitchingAccounts value)? switchingAccounts,
required TResult orElse(),
}) {
if (switchingAccounts != null) {
return switchingAccounts(this);
}
return orElse();
}
}
abstract class _SwitchingAccounts implements AuthenticationState {
const factory _SwitchingAccounts() = _$_SwitchingAccounts;
}

View File

@@ -8,4 +8,5 @@ class AuthenticationState with _$AuthenticationState {
required String localUserId, required String localUserId,
required int apiVersion, required int apiVersion,
}) = _Authenticated; }) = _Authenticated;
const factory AuthenticationState.switchingAccounts() = _SwitchingAccounts;
} }

View File

@@ -38,6 +38,7 @@ import 'package:paperless_mobile/features/login/model/login_form_credentials.dar
import 'package:paperless_mobile/features/login/services/authentication_service.dart'; import 'package:paperless_mobile/features/login/services/authentication_service.dart';
import 'package:paperless_mobile/features/login/view/login_page.dart'; import 'package:paperless_mobile/features/login/view/login_page.dart';
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart'; import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
import 'package:paperless_mobile/features/settings/view/pages/switching_accounts_page.dart';
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart'; import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
import 'package:paperless_mobile/features/sharing/share_intent_queue.dart'; import 'package:paperless_mobile/features/sharing/share_intent_queue.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
@@ -270,6 +271,7 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
paperlessProviderFactory: widget.paperlessProviderFactory, paperlessProviderFactory: widget.paperlessProviderFactory,
localUserId: localUserId, localUserId: localUserId,
), ),
switchingAccounts: () => const SwitchingAccountsPage(),
); );
}, },
); );