mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-08 10:07:51 -06:00
feat: Restructure providers and repositories (WIP, not compiling)
This commit is contained in:
@@ -14,15 +14,15 @@ class LocalUserAccount extends HiveObject {
|
|||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
@HiveField(4)
|
@HiveField(4)
|
||||||
LocalUserSettings settings;
|
final LocalUserSettings settings;
|
||||||
|
|
||||||
@HiveField(5)
|
@HiveField(6)
|
||||||
UserModel paperlessUser;
|
final int paperlessUserId;
|
||||||
|
|
||||||
LocalUserAccount({
|
LocalUserAccount({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.serverUrl,
|
required this.serverUrl,
|
||||||
required this.settings,
|
required this.settings,
|
||||||
required this.paperlessUser,
|
required this.paperlessUserId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
10
lib/core/factory/paperless_api_factory.dart
Normal file
10
lib/core/factory/paperless_api_factory.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
|
||||||
|
abstract class PaperlessApiFactory {
|
||||||
|
PaperlessDocumentsApi createDocumentsApi(Dio dio, {required int apiVersion});
|
||||||
|
PaperlessSavedViewsApi createSavedViewsApi(Dio dio, {required int apiVersion});
|
||||||
|
PaperlessLabelsApi createLabelsApi(Dio dio, {required int apiVersion});
|
||||||
|
PaperlessServerStatsApi createServerStatsApi(Dio dio, {required int apiVersion});
|
||||||
|
PaperlessTasksApi createTasksApi(Dio dio, {required int apiVersion});
|
||||||
|
}
|
||||||
35
lib/core/factory/paperless_api_factory_impl.dart
Normal file
35
lib/core/factory/paperless_api_factory_impl.dart
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
|
import 'package:paperless_mobile/core/security/session_manager.dart';
|
||||||
|
|
||||||
|
class PaperlessApiFactoryImpl implements PaperlessApiFactory {
|
||||||
|
final SessionManager sessionManager;
|
||||||
|
|
||||||
|
PaperlessApiFactoryImpl(this.sessionManager);
|
||||||
|
|
||||||
|
@override
|
||||||
|
PaperlessDocumentsApi createDocumentsApi(Dio dio, {required int apiVersion}) {
|
||||||
|
return PaperlessDocumentsApiImpl(dio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PaperlessLabelsApi createLabelsApi(Dio dio, {required int apiVersion}) {
|
||||||
|
return PaperlessLabelApiImpl(dio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PaperlessSavedViewsApi createSavedViewsApi(Dio dio, {required int apiVersion}) {
|
||||||
|
return PaperlessSavedViewsApiImpl(dio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PaperlessServerStatsApi createServerStatsApi(Dio dio, {required int apiVersion}) {
|
||||||
|
return PaperlessServerStatsApiImpl(dio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PaperlessTasksApi createTasksApi(Dio dio, {required int apiVersion}) {
|
||||||
|
return PaperlessTasksApiImpl(dio);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/repository/saved_view_repository_state.dart';
|
import 'package:paperless_mobile/core/repository/saved_view_repository_state.dart';
|
||||||
@@ -25,6 +26,10 @@ class SavedViewRepository extends HydratedCubit<SavedViewRepositoryState> {
|
|||||||
|
|
||||||
SavedViewRepository(this._api) : super(const SavedViewRepositoryState());
|
SavedViewRepository(this._api) : super(const SavedViewRepositoryState());
|
||||||
|
|
||||||
|
Future<void> initialize() {
|
||||||
|
return findAll();
|
||||||
|
}
|
||||||
|
|
||||||
Future<SavedView> create(SavedView object) async {
|
Future<SavedView> create(SavedView object) async {
|
||||||
final created = await _api.save(object);
|
final created = await _api.save(object);
|
||||||
final updatedState = {...state.savedViews}..putIfAbsent(created.id!, () => created);
|
final updatedState = {...state.savedViews}..putIfAbsent(created.id!, () => created);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:dio/io.dart';
|
import 'package:dio/io.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/retry_on_connection_change_interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/retry_on_connection_change_interceptor.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
||||||
@@ -10,15 +10,10 @@ import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
|||||||
/// Manages the security context, authentication and base request URL for
|
/// Manages the security context, authentication and base request URL for
|
||||||
/// an underlying [Dio] client which is injected into all services
|
/// an underlying [Dio] client which is injected into all services
|
||||||
/// requiring authenticated access to the Paperless HTTP API.
|
/// requiring authenticated access to the Paperless HTTP API.
|
||||||
class SessionManager {
|
class SessionManager extends ValueNotifier<Dio> {
|
||||||
final Dio _client;
|
Dio get client => value;
|
||||||
PaperlessServerInformationModel _serverInformation;
|
|
||||||
|
|
||||||
Dio get client => _client;
|
SessionManager([List<Interceptor> interceptors = const []]) : super(_initDio(interceptors));
|
||||||
|
|
||||||
SessionManager([List<Interceptor> interceptors = const []])
|
|
||||||
: _client = _initDio(interceptors),
|
|
||||||
_serverInformation = PaperlessServerInformationModel();
|
|
||||||
|
|
||||||
static Dio _initDio(List<Interceptor> interceptors) {
|
static Dio _initDio(List<Interceptor> interceptors) {
|
||||||
//en- and decoded by utf8 by default
|
//en- and decoded by utf8 by default
|
||||||
@@ -48,7 +43,6 @@ class SessionManager {
|
|||||||
String? baseUrl,
|
String? baseUrl,
|
||||||
String? authToken,
|
String? authToken,
|
||||||
ClientCertificate? clientCertificate,
|
ClientCertificate? clientCertificate,
|
||||||
PaperlessServerInformationModel? serverInformation,
|
|
||||||
}) {
|
}) {
|
||||||
if (clientCertificate != null) {
|
if (clientCertificate != null) {
|
||||||
final context = SecurityContext()
|
final context = SecurityContext()
|
||||||
@@ -81,15 +75,13 @@ class SessionManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverInformation != null) {
|
notifyListeners();
|
||||||
_serverInformation = serverInformation;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetSettings() {
|
void resetSettings() {
|
||||||
client.httpClientAdapter = IOHttpClientAdapter();
|
client.httpClientAdapter = IOHttpClientAdapter();
|
||||||
client.options.baseUrl = '';
|
client.options.baseUrl = '';
|
||||||
client.options.headers.remove(HttpHeaders.authorizationHeader);
|
client.options.headers.remove(HttpHeaders.authorizationHeader);
|
||||||
_serverInformation = PaperlessServerInformationModel();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,35 +52,12 @@ class HomePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
||||||
int _currentIndex = 0;
|
int _currentIndex = 0;
|
||||||
final DocumentScannerCubit _scannerCubit = DocumentScannerCubit();
|
|
||||||
late final DocumentsCubit _documentsCubit;
|
|
||||||
late final InboxCubit _inboxCubit;
|
|
||||||
late final SavedViewCubit _savedViewCubit;
|
|
||||||
late Timer _inboxTimer;
|
late Timer _inboxTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
_initializeData(context);
|
|
||||||
final userId =
|
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!.currentLoggedInUser;
|
|
||||||
_documentsCubit = DocumentsCubit(
|
|
||||||
context.read(),
|
|
||||||
context.read(),
|
|
||||||
context.read(),
|
|
||||||
Hive.box<LocalUserAppState>(HiveBoxes.localUserAppState).get(userId)!,
|
|
||||||
)..reload();
|
|
||||||
_savedViewCubit = SavedViewCubit(
|
|
||||||
context.read(),
|
|
||||||
context.read(),
|
|
||||||
)..reload();
|
|
||||||
_inboxCubit = InboxCubit(
|
|
||||||
context.read(),
|
|
||||||
context.read(),
|
|
||||||
context.read(),
|
|
||||||
context.read(),
|
|
||||||
);
|
|
||||||
_listenToInboxChanges();
|
_listenToInboxChanges();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
_listenForReceivedFiles();
|
_listenForReceivedFiles();
|
||||||
@@ -97,7 +74,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
} else {
|
} else {
|
||||||
_inboxCubit.refreshItemsInInboxCount();
|
context.read<InboxCubit>().refreshItemsInInboxCount();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -127,9 +104,6 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
_inboxTimer.cancel();
|
_inboxTimer.cancel();
|
||||||
_inboxCubit.close();
|
|
||||||
_documentsCubit.close();
|
|
||||||
_savedViewCubit.close();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +221,6 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
),
|
),
|
||||||
label: S.of(context)!.inbox,
|
label: S.of(context)!.inbox,
|
||||||
badgeBuilder: (icon) => BlocBuilder<InboxCubit, InboxState>(
|
badgeBuilder: (icon) => BlocBuilder<InboxCubit, InboxState>(
|
||||||
bloc: _inboxCubit,
|
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state.itemsInInboxCount > 0) {
|
if (state.itemsInInboxCount > 0) {
|
||||||
return Badge.count(
|
return Badge.count(
|
||||||
@@ -261,31 +234,10 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
final routes = <Widget>[
|
final routes = <Widget>[
|
||||||
MultiBlocProvider(
|
const DocumentsPage(),
|
||||||
// key: ValueKey(userId),
|
const ScannerPage(),
|
||||||
providers: [
|
const LabelsPage(),
|
||||||
BlocProvider.value(value: _documentsCubit),
|
const InboxPage(),
|
||||||
BlocProvider.value(value: _savedViewCubit),
|
|
||||||
],
|
|
||||||
child: const DocumentsPage(),
|
|
||||||
),
|
|
||||||
BlocProvider.value(
|
|
||||||
value: _scannerCubit,
|
|
||||||
child: const ScannerPage(),
|
|
||||||
),
|
|
||||||
MultiBlocProvider(
|
|
||||||
// key: ValueKey(userId),
|
|
||||||
providers: [
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) => LabelCubit(context.read()),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
child: const LabelsPage(),
|
|
||||||
),
|
|
||||||
BlocProvider<InboxCubit>.value(
|
|
||||||
value: _inboxCubit,
|
|
||||||
child: const InboxPage(),
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return MultiBlocListener(
|
return MultiBlocListener(
|
||||||
|
|||||||
@@ -1,29 +1,139 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/src/widgets/framework.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
|
import 'package:hive_flutter/adapters.dart';
|
||||||
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/server_information_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/server_information_cubit.dart';
|
||||||
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
|
import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
|
||||||
|
import 'package:paperless_mobile/core/security/session_manager.dart';
|
||||||
|
import 'package:paperless_mobile/core/service/dio_file_service.dart';
|
||||||
|
import 'package:paperless_mobile/features/document_scan/cubit/document_scanner_cubit.dart';
|
||||||
|
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/home/view/home_page.dart';
|
import 'package:paperless_mobile/features/home/view/home_page.dart';
|
||||||
|
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
|
||||||
|
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
|
||||||
|
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
||||||
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart';
|
import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class HomeRoute extends StatelessWidget {
|
class HomeRoute extends StatelessWidget {
|
||||||
const HomeRoute({super.key});
|
final String localUserId;
|
||||||
|
final int paperlessApiVersion;
|
||||||
|
final PaperlessApiFactory paperlessProviderFactory;
|
||||||
|
|
||||||
|
const HomeRoute({
|
||||||
|
super.key,
|
||||||
|
required this.paperlessApiVersion,
|
||||||
|
required this.paperlessProviderFactory,
|
||||||
|
required this.localUserId,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiBlocProvider(
|
return GlobalSettingsBuilder(
|
||||||
providers: [
|
builder: (context, settings) {
|
||||||
BlocProvider(
|
final currentLocalUserId = settings.currentLoggedInUser!;
|
||||||
create: (context) => TaskStatusCubit(
|
return MultiProvider(
|
||||||
context.read(),
|
providers: [
|
||||||
),
|
Provider<CacheManager>(
|
||||||
),
|
create: (context) => CacheManager(
|
||||||
BlocProvider<ServerInformationCubit>(
|
Config(
|
||||||
create: (context) => ServerInformationCubit(
|
localUserId,
|
||||||
context.read(),
|
fileService: DioFileService(context.read<SessionManager>().client),
|
||||||
)..updateInformation(),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
child: HomePage(),
|
ProxyProvider<SessionManager, PaperlessDocumentsApi>(
|
||||||
|
update: (context, value, previous) => paperlessProviderFactory.createDocumentsApi(
|
||||||
|
value.client,
|
||||||
|
apiVersion: paperlessApiVersion,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ProxyProvider<SessionManager, PaperlessLabelsApi>(
|
||||||
|
update: (context, value, previous) => paperlessProviderFactory.createLabelsApi(
|
||||||
|
value.client,
|
||||||
|
apiVersion: paperlessApiVersion,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ProxyProvider<SessionManager, PaperlessSavedViewsApi>(
|
||||||
|
update: (context, value, previous) => paperlessProviderFactory.createSavedViewsApi(
|
||||||
|
value.client,
|
||||||
|
apiVersion: paperlessApiVersion,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ProxyProvider<SessionManager, PaperlessServerStatsApi>(
|
||||||
|
update: (context, value, previous) => paperlessProviderFactory.createServerStatsApi(
|
||||||
|
value.client,
|
||||||
|
apiVersion: paperlessApiVersion,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ProxyProvider<SessionManager, PaperlessTasksApi>(
|
||||||
|
update: (context, value, previous) => paperlessProviderFactory.createTasksApi(
|
||||||
|
value.client,
|
||||||
|
apiVersion: paperlessApiVersion,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
builder: (context, child) {
|
||||||
|
return MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ProxyProvider<PaperlessLabelsApi, LabelRepository>(
|
||||||
|
update: (context, value, previous) => LabelRepository(value)..initialize(),
|
||||||
|
),
|
||||||
|
ProxyProvider<PaperlessSavedViewsApi, SavedViewRepository>(
|
||||||
|
update: (context, value, previous) => SavedViewRepository(value)..initialize(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
builder: (context, child) {
|
||||||
|
return MultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
ProxyProvider3<PaperlessDocumentsApi, DocumentChangedNotifier, LabelRepository,
|
||||||
|
DocumentsCubit>(
|
||||||
|
update: (context, docApi, notifier, labelRepo, previous) => DocumentsCubit(
|
||||||
|
docApi,
|
||||||
|
notifier,
|
||||||
|
labelRepo,
|
||||||
|
Hive.box<LocalUserAppState>(HiveBoxes.localUserAppState)
|
||||||
|
.get(currentLocalUserId)!,
|
||||||
|
)..reload(),
|
||||||
|
),
|
||||||
|
Provider(create: (context) => DocumentScannerCubit()),
|
||||||
|
ProxyProvider4<PaperlessDocumentsApi, PaperlessServerStatsApi, LabelRepository,
|
||||||
|
DocumentChangedNotifier, InboxCubit>(
|
||||||
|
update: (context, docApi, statsApi, labelRepo, notifier, previous) =>
|
||||||
|
InboxCubit(
|
||||||
|
docApi,
|
||||||
|
statsApi,
|
||||||
|
labelRepo,
|
||||||
|
notifier,
|
||||||
|
)..initialize(),
|
||||||
|
),
|
||||||
|
ProxyProvider2<SavedViewRepository, LabelRepository, SavedViewCubit>(
|
||||||
|
update: (context, savedViewRepo, labelRepo, previous) => SavedViewCubit(
|
||||||
|
savedViewRepo,
|
||||||
|
labelRepo,
|
||||||
|
)..initialize(),
|
||||||
|
),
|
||||||
|
ProxyProvider<PaperlessServerStatsApi, ServerInformationCubit>(
|
||||||
|
update: (context, value, previous) => ServerInformationCubit(value),
|
||||||
|
),
|
||||||
|
ProxyProvider<LabelRepository, LabelCubit>(
|
||||||
|
update: (context, value, previous) => LabelCubit(value),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: const HomePage(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,16 +52,18 @@ class InboxCubit extends HydratedCubit<InboxState> with DocumentPagingBlocMixin
|
|||||||
emit(state.copyWith(labels: labels));
|
emit(state.copyWith(labels: labels));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
refreshItemsInInboxCount(false);
|
|
||||||
loadInbox();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshItemsInInboxCount([bool shouldLoadInbox = true]) async {
|
Future<void> initialize() async {
|
||||||
|
await refreshItemsInInboxCount(false);
|
||||||
|
await loadInbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> refreshItemsInInboxCount([bool shouldLoadInbox = true]) async {
|
||||||
final stats = await _statsApi.getServerStatistics();
|
final stats = await _statsApi.getServerStatistics();
|
||||||
|
|
||||||
if (stats.documentsInInbox != state.itemsInInboxCount && shouldLoadInbox) {
|
if (stats.documentsInInbox != state.itemsInInboxCount && shouldLoadInbox) {
|
||||||
loadInbox();
|
await loadInbox();
|
||||||
}
|
}
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ import 'dart:typed_data';
|
|||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
|
||||||
import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
|
|
||||||
import 'package:paperless_mobile/core/security/session_manager.dart';
|
import 'package:paperless_mobile/core/security/session_manager.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||||
@@ -19,29 +18,22 @@ import 'package:paperless_mobile/features/login/services/authentication_service.
|
|||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_settings.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
|
||||||
part 'authentication_state.dart';
|
part 'authentication_state.dart';
|
||||||
|
part 'authentication_cubit.freezed.dart';
|
||||||
|
|
||||||
class AuthenticationCubit extends Cubit<AuthenticationState> {
|
class AuthenticationCubit extends Cubit<AuthenticationState> {
|
||||||
|
final PaperlessUserApi _userApi;
|
||||||
final LocalAuthenticationService _localAuthService;
|
final LocalAuthenticationService _localAuthService;
|
||||||
final PaperlessAuthenticationApi _authApi;
|
final PaperlessAuthenticationApi _authApi;
|
||||||
final SessionManager _sessionManager;
|
final SessionManager _sessionManager;
|
||||||
final LabelRepository _labelRepository;
|
|
||||||
final SavedViewRepository _savedViewRepository;
|
|
||||||
final PaperlessServerStatsApi _serverStatsApi;
|
|
||||||
final PaperlessUserApi _userApi;
|
|
||||||
final PaperlessUserApiV3? _userApiV3;
|
|
||||||
|
|
||||||
AuthenticationCubit(
|
AuthenticationCubit(
|
||||||
this._localAuthService,
|
this._localAuthService,
|
||||||
this._authApi,
|
this._authApi,
|
||||||
this._sessionManager,
|
this._sessionManager,
|
||||||
this._labelRepository,
|
this._userApi,
|
||||||
this._savedViewRepository,
|
) : super(const AuthenticationState.unauthenticated());
|
||||||
this._serverStatsApi,
|
|
||||||
this._userApi, {
|
|
||||||
PaperlessUserApiV3? userApiV3,
|
|
||||||
}) : _userApiV3 = userApiV3,
|
|
||||||
super(const AuthenticationState());
|
|
||||||
|
|
||||||
Future<void> login({
|
Future<void> login({
|
||||||
required LoginFormCredentials credentials,
|
required LoginFormCredentials credentials,
|
||||||
@@ -66,14 +58,10 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
globalSettings.currentLoggedInUser = localUserId;
|
globalSettings.currentLoggedInUser = localUserId;
|
||||||
await globalSettings.save();
|
await globalSettings.save();
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
AuthenticationState(
|
AuthenticationState.authenticated(
|
||||||
isAuthenticated: true,
|
|
||||||
username: credentials.username,
|
|
||||||
localUserId: localUserId,
|
|
||||||
fullName: serverUser.fullName,
|
|
||||||
apiVersion: apiVersion,
|
apiVersion: apiVersion,
|
||||||
|
localUserId: localUserId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -116,26 +104,18 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
_sessionManager.updateSettings(
|
_sessionManager.updateSettings(
|
||||||
authToken: credentials!.token,
|
authToken: credentials!.token,
|
||||||
clientCertificate: credentials.clientCertificate,
|
clientCertificate: credentials.clientCertificate,
|
||||||
serverInformation: PaperlessServerInformationModel(),
|
|
||||||
baseUrl: account.serverUrl,
|
baseUrl: account.serverUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
await _reloadRepositories();
|
|
||||||
globalSettings.currentLoggedInUser = localUserId;
|
globalSettings.currentLoggedInUser = localUserId;
|
||||||
await globalSettings.save();
|
await globalSettings.save();
|
||||||
|
|
||||||
final response = await _sessionManager.client.get("/api/");
|
final response = await _sessionManager.client.get("/api/");
|
||||||
final apiVersion = response.headers["x-api-version"] as int;
|
final apiVersion = response.headers["x-api-version"] as int;
|
||||||
|
emit(AuthenticationState.authenticated(
|
||||||
emit(
|
localUserId: localUserId,
|
||||||
AuthenticationState(
|
apiVersion: apiVersion,
|
||||||
isAuthenticated: true,
|
));
|
||||||
username: account.paperlessUser.username,
|
|
||||||
fullName: account.paperlessUser.fullName,
|
|
||||||
localUserId: localUserId,
|
|
||||||
apiVersion: apiVersion,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> addAccount({
|
Future<String> addAccount({
|
||||||
@@ -179,19 +159,19 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
///
|
///
|
||||||
Future<void> restoreSessionState() async {
|
Future<void> restoreSessionState() async {
|
||||||
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
final userId = globalSettings.currentLoggedInUser;
|
final localUserId = globalSettings.currentLoggedInUser;
|
||||||
if (userId == null) {
|
if (localUserId == null) {
|
||||||
// If there is nothing to restore, we can quit here.
|
// If there is nothing to restore, we can quit here.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final userAccount = Hive.box<LocalUserAccount>(HiveBoxes.localUserAccount).get(userId)!;
|
final userAccount = Hive.box<LocalUserAccount>(HiveBoxes.localUserAccount).get(localUserId)!;
|
||||||
|
|
||||||
if (userAccount.settings.isBiometricAuthenticationEnabled) {
|
if (userAccount.settings.isBiometricAuthenticationEnabled) {
|
||||||
final localAuthSuccess =
|
final localAuthSuccess =
|
||||||
await _localAuthService.authenticateLocalUser("Authenticate to log back in"); //TODO: INTL
|
await _localAuthService.authenticateLocalUser("Authenticate to log back in"); //TODO: INTL
|
||||||
if (!localAuthSuccess) {
|
if (!localAuthSuccess) {
|
||||||
emit(const AuthenticationState(showBiometricAuthenticationScreen: true));
|
emit(const AuthenticationState.requriresLocalAuthentication());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,18 +187,13 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
clientCertificate: authentication.clientCertificate,
|
clientCertificate: authentication.clientCertificate,
|
||||||
authToken: authentication.token,
|
authToken: authentication.token,
|
||||||
baseUrl: userAccount.serverUrl,
|
baseUrl: userAccount.serverUrl,
|
||||||
serverInformation: PaperlessServerInformationModel(),
|
|
||||||
);
|
);
|
||||||
final response = await _sessionManager.client.get("/api/");
|
final response = await _sessionManager.client.get("/api/");
|
||||||
final apiVersion = response.headers["x-api-version"] as int;
|
final apiVersion = response.headers["x-api-version"] as int;
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
AuthenticationState(
|
AuthenticationState.authenticated(
|
||||||
isAuthenticated: true,
|
|
||||||
showBiometricAuthenticationScreen: false,
|
|
||||||
username: userAccount.paperlessUser.username,
|
|
||||||
apiVersion: apiVersion,
|
apiVersion: apiVersion,
|
||||||
fullName: userAccount.paperlessUser.fullName,
|
localUserId: localUserId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -229,7 +204,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
globalSettings
|
globalSettings
|
||||||
..currentLoggedInUser = null
|
..currentLoggedInUser = null
|
||||||
..save();
|
..save();
|
||||||
emit(const AuthenticationState());
|
emit(const AuthenticationState.unauthenticated());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List> _getEncryptedBoxKey() async {
|
Future<Uint8List> _getEncryptedBoxKey() async {
|
||||||
@@ -254,23 +229,12 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _resetExternalState() {
|
Future<void> _resetExternalState() async {
|
||||||
_sessionManager.resetSettings();
|
_sessionManager.resetSettings();
|
||||||
return Future.wait([
|
await HydratedBloc.storage.clear();
|
||||||
HydratedBloc.storage.clear(),
|
|
||||||
_labelRepository.clear(),
|
|
||||||
_savedViewRepository.clear(),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _reloadRepositories() {
|
Future<int> _addUser(
|
||||||
return Future.wait([
|
|
||||||
_labelRepository.initialize(),
|
|
||||||
_savedViewRepository.findAll(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<UserModel> _addUser(
|
|
||||||
String localUserId,
|
String localUserId,
|
||||||
String serverUrl,
|
String serverUrl,
|
||||||
LoginFormCredentials credentials,
|
LoginFormCredentials credentials,
|
||||||
@@ -303,7 +267,6 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final serverUserId = await _userApi.findCurrentUserId();
|
final serverUserId = await _userApi.findCurrentUserId();
|
||||||
final serverUser = await _userApi.find(serverUserId);
|
|
||||||
|
|
||||||
// Create user account
|
// Create user account
|
||||||
await userAccountBox.put(
|
await userAccountBox.put(
|
||||||
@@ -312,7 +275,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
id: localUserId,
|
id: localUserId,
|
||||||
settings: LocalUserSettings(),
|
settings: LocalUserSettings(),
|
||||||
serverUrl: serverUrl,
|
serverUrl: serverUrl,
|
||||||
paperlessUser: serverUser,
|
paperlessUserId: 1,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -332,6 +295,6 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
userCredentialsBox.close();
|
userCredentialsBox.close();
|
||||||
return serverUser;
|
return serverUserId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
465
lib/features/login/cubit/authentication_cubit.freezed.dart
Normal file
465
lib/features/login/cubit/authentication_cubit.freezed.dart
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'authentication_cubit.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$AuthenticationState {
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unauthenticated,
|
||||||
|
required TResult Function() requriresLocalAuthentication,
|
||||||
|
required TResult Function(String localUserId, int apiVersion) authenticated,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unauthenticated,
|
||||||
|
TResult? Function()? requriresLocalAuthentication,
|
||||||
|
TResult? Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unauthenticated,
|
||||||
|
TResult Function()? requriresLocalAuthentication,
|
||||||
|
TResult Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Unauthenticated value) unauthenticated,
|
||||||
|
required TResult Function(_RequiresLocalAuthentication value)
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
required TResult Function(_Authenticated value) authenticated,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult? Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult? Function(_Authenticated value)? authenticated,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult Function(_Authenticated value)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $AuthenticationStateCopyWith<$Res> {
|
||||||
|
factory $AuthenticationStateCopyWith(
|
||||||
|
AuthenticationState value, $Res Function(AuthenticationState) then) =
|
||||||
|
_$AuthenticationStateCopyWithImpl<$Res, AuthenticationState>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$AuthenticationStateCopyWithImpl<$Res, $Val extends AuthenticationState>
|
||||||
|
implements $AuthenticationStateCopyWith<$Res> {
|
||||||
|
_$AuthenticationStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$_UnauthenticatedCopyWith<$Res> {
|
||||||
|
factory _$$_UnauthenticatedCopyWith(
|
||||||
|
_$_Unauthenticated value, $Res Function(_$_Unauthenticated) then) =
|
||||||
|
__$$_UnauthenticatedCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$_UnauthenticatedCopyWithImpl<$Res>
|
||||||
|
extends _$AuthenticationStateCopyWithImpl<$Res, _$_Unauthenticated>
|
||||||
|
implements _$$_UnauthenticatedCopyWith<$Res> {
|
||||||
|
__$$_UnauthenticatedCopyWithImpl(
|
||||||
|
_$_Unauthenticated _value, $Res Function(_$_Unauthenticated) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_Unauthenticated implements _Unauthenticated {
|
||||||
|
const _$_Unauthenticated();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AuthenticationState.unauthenticated()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$_Unauthenticated);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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,
|
||||||
|
}) {
|
||||||
|
return unauthenticated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unauthenticated,
|
||||||
|
TResult? Function()? requriresLocalAuthentication,
|
||||||
|
TResult? Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
}) {
|
||||||
|
return unauthenticated?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unauthenticated,
|
||||||
|
TResult Function()? requriresLocalAuthentication,
|
||||||
|
TResult Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (unauthenticated != null) {
|
||||||
|
return unauthenticated();
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}) {
|
||||||
|
return unauthenticated(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult? Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult? Function(_Authenticated value)? authenticated,
|
||||||
|
}) {
|
||||||
|
return unauthenticated?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult Function(_Authenticated value)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (unauthenticated != null) {
|
||||||
|
return unauthenticated(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Unauthenticated implements AuthenticationState {
|
||||||
|
const factory _Unauthenticated() = _$_Unauthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$_RequiresLocalAuthenticationCopyWith<$Res> {
|
||||||
|
factory _$$_RequiresLocalAuthenticationCopyWith(
|
||||||
|
_$_RequiresLocalAuthentication value,
|
||||||
|
$Res Function(_$_RequiresLocalAuthentication) then) =
|
||||||
|
__$$_RequiresLocalAuthenticationCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$_RequiresLocalAuthenticationCopyWithImpl<$Res>
|
||||||
|
extends _$AuthenticationStateCopyWithImpl<$Res,
|
||||||
|
_$_RequiresLocalAuthentication>
|
||||||
|
implements _$$_RequiresLocalAuthenticationCopyWith<$Res> {
|
||||||
|
__$$_RequiresLocalAuthenticationCopyWithImpl(
|
||||||
|
_$_RequiresLocalAuthentication _value,
|
||||||
|
$Res Function(_$_RequiresLocalAuthentication) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
|
||||||
|
const _$_RequiresLocalAuthentication();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AuthenticationState.requriresLocalAuthentication()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$_RequiresLocalAuthentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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,
|
||||||
|
}) {
|
||||||
|
return requriresLocalAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unauthenticated,
|
||||||
|
TResult? Function()? requriresLocalAuthentication,
|
||||||
|
TResult? Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
}) {
|
||||||
|
return requriresLocalAuthentication?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unauthenticated,
|
||||||
|
TResult Function()? requriresLocalAuthentication,
|
||||||
|
TResult Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (requriresLocalAuthentication != null) {
|
||||||
|
return requriresLocalAuthentication();
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}) {
|
||||||
|
return requriresLocalAuthentication(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult? Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult? Function(_Authenticated value)? authenticated,
|
||||||
|
}) {
|
||||||
|
return requriresLocalAuthentication?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult Function(_Authenticated value)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (requriresLocalAuthentication != null) {
|
||||||
|
return requriresLocalAuthentication(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _RequiresLocalAuthentication implements AuthenticationState {
|
||||||
|
const factory _RequiresLocalAuthentication() = _$_RequiresLocalAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$_AuthenticatedCopyWith<$Res> {
|
||||||
|
factory _$$_AuthenticatedCopyWith(
|
||||||
|
_$_Authenticated value, $Res Function(_$_Authenticated) then) =
|
||||||
|
__$$_AuthenticatedCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String localUserId, int apiVersion});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$_AuthenticatedCopyWithImpl<$Res>
|
||||||
|
extends _$AuthenticationStateCopyWithImpl<$Res, _$_Authenticated>
|
||||||
|
implements _$$_AuthenticatedCopyWith<$Res> {
|
||||||
|
__$$_AuthenticatedCopyWithImpl(
|
||||||
|
_$_Authenticated _value, $Res Function(_$_Authenticated) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? localUserId = null,
|
||||||
|
Object? apiVersion = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$_Authenticated(
|
||||||
|
localUserId: null == localUserId
|
||||||
|
? _value.localUserId
|
||||||
|
: localUserId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
apiVersion: null == apiVersion
|
||||||
|
? _value.apiVersion
|
||||||
|
: apiVersion // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_Authenticated implements _Authenticated {
|
||||||
|
const _$_Authenticated({required this.localUserId, required this.apiVersion});
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String localUserId;
|
||||||
|
@override
|
||||||
|
final int apiVersion;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AuthenticationState.authenticated(localUserId: $localUserId, apiVersion: $apiVersion)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$_Authenticated &&
|
||||||
|
(identical(other.localUserId, localUserId) ||
|
||||||
|
other.localUserId == localUserId) &&
|
||||||
|
(identical(other.apiVersion, apiVersion) ||
|
||||||
|
other.apiVersion == apiVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, localUserId, apiVersion);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$_AuthenticatedCopyWith<_$_Authenticated> get copyWith =>
|
||||||
|
__$$_AuthenticatedCopyWithImpl<_$_Authenticated>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unauthenticated,
|
||||||
|
required TResult Function() requriresLocalAuthentication,
|
||||||
|
required TResult Function(String localUserId, int apiVersion) authenticated,
|
||||||
|
}) {
|
||||||
|
return authenticated(localUserId, apiVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unauthenticated,
|
||||||
|
TResult? Function()? requriresLocalAuthentication,
|
||||||
|
TResult? Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
}) {
|
||||||
|
return authenticated?.call(localUserId, apiVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unauthenticated,
|
||||||
|
TResult Function()? requriresLocalAuthentication,
|
||||||
|
TResult Function(String localUserId, int apiVersion)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (authenticated != null) {
|
||||||
|
return authenticated(localUserId, apiVersion);
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}) {
|
||||||
|
return authenticated(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult? Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult? Function(_Authenticated value)? authenticated,
|
||||||
|
}) {
|
||||||
|
return authenticated?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Unauthenticated value)? unauthenticated,
|
||||||
|
TResult Function(_RequiresLocalAuthentication value)?
|
||||||
|
requriresLocalAuthentication,
|
||||||
|
TResult Function(_Authenticated value)? authenticated,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (authenticated != null) {
|
||||||
|
return authenticated(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Authenticated implements AuthenticationState {
|
||||||
|
const factory _Authenticated(
|
||||||
|
{required final String localUserId,
|
||||||
|
required final int apiVersion}) = _$_Authenticated;
|
||||||
|
|
||||||
|
String get localUserId;
|
||||||
|
int get apiVersion;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$_AuthenticatedCopyWith<_$_Authenticated> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
@@ -1,48 +1,11 @@
|
|||||||
part of 'authentication_cubit.dart';
|
part of 'authentication_cubit.dart';
|
||||||
|
|
||||||
class AuthenticationState with EquatableMixin {
|
@freezed
|
||||||
final bool showBiometricAuthenticationScreen;
|
class AuthenticationState with _$AuthenticationState {
|
||||||
final bool isAuthenticated;
|
const factory AuthenticationState.unauthenticated() = _Unauthenticated;
|
||||||
final String? username;
|
const factory AuthenticationState.requriresLocalAuthentication() = _RequiresLocalAuthentication;
|
||||||
final String? fullName;
|
const factory AuthenticationState.authenticated({
|
||||||
final String? localUserId;
|
required String localUserId,
|
||||||
final int? apiVersion;
|
required int apiVersion,
|
||||||
|
}) = _Authenticated;
|
||||||
const AuthenticationState({
|
|
||||||
this.isAuthenticated = false,
|
|
||||||
this.showBiometricAuthenticationScreen = false,
|
|
||||||
this.username,
|
|
||||||
this.fullName,
|
|
||||||
this.localUserId,
|
|
||||||
this.apiVersion,
|
|
||||||
});
|
|
||||||
|
|
||||||
AuthenticationState copyWith({
|
|
||||||
bool? isAuthenticated,
|
|
||||||
bool? showBiometricAuthenticationScreen,
|
|
||||||
String? username,
|
|
||||||
String? fullName,
|
|
||||||
String? localUserId,
|
|
||||||
int? apiVersion,
|
|
||||||
}) {
|
|
||||||
return AuthenticationState(
|
|
||||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
|
||||||
showBiometricAuthenticationScreen:
|
|
||||||
showBiometricAuthenticationScreen ?? this.showBiometricAuthenticationScreen,
|
|
||||||
username: username ?? this.username,
|
|
||||||
fullName: fullName ?? this.fullName,
|
|
||||||
localUserId: localUserId ?? this.localUserId,
|
|
||||||
apiVersion: apiVersion ?? this.apiVersion,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [
|
|
||||||
localUserId,
|
|
||||||
username,
|
|
||||||
fullName,
|
|
||||||
isAuthenticated,
|
|
||||||
showBiometricAuthenticationScreen,
|
|
||||||
apiVersion,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
48
lib/features/login/cubit/old_authentication_state.dart
Normal file
48
lib/features/login/cubit/old_authentication_state.dart
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class OldAuthenticationState with EquatableMixin {
|
||||||
|
final bool showBiometricAuthenticationScreen;
|
||||||
|
final bool isAuthenticated;
|
||||||
|
final String? username;
|
||||||
|
final String? fullName;
|
||||||
|
final String? localUserId;
|
||||||
|
final int? apiVersion;
|
||||||
|
|
||||||
|
const OldAuthenticationState({
|
||||||
|
this.isAuthenticated = false,
|
||||||
|
this.showBiometricAuthenticationScreen = false,
|
||||||
|
this.username,
|
||||||
|
this.fullName,
|
||||||
|
this.localUserId,
|
||||||
|
this.apiVersion,
|
||||||
|
});
|
||||||
|
|
||||||
|
OldAuthenticationState copyWith({
|
||||||
|
bool? isAuthenticated,
|
||||||
|
bool? showBiometricAuthenticationScreen,
|
||||||
|
String? username,
|
||||||
|
String? fullName,
|
||||||
|
String? localUserId,
|
||||||
|
int? apiVersion,
|
||||||
|
}) {
|
||||||
|
return OldAuthenticationState(
|
||||||
|
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||||
|
showBiometricAuthenticationScreen:
|
||||||
|
showBiometricAuthenticationScreen ?? this.showBiometricAuthenticationScreen,
|
||||||
|
username: username ?? this.username,
|
||||||
|
fullName: fullName ?? this.fullName,
|
||||||
|
localUserId: localUserId ?? this.localUserId,
|
||||||
|
apiVersion: apiVersion ?? this.apiVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
localUserId,
|
||||||
|
username,
|
||||||
|
fullName,
|
||||||
|
isAuthenticated,
|
||||||
|
showBiometricAuthenticationScreen,
|
||||||
|
apiVersion,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
|||||||
class UserAvatar extends StatelessWidget {
|
class UserAvatar extends StatelessWidget {
|
||||||
final String userId;
|
final String userId;
|
||||||
final LocalUserAccount account;
|
final LocalUserAccount account;
|
||||||
|
|
||||||
const UserAvatar({
|
const UserAvatar({
|
||||||
super.key,
|
super.key,
|
||||||
required this.userId,
|
required this.userId,
|
||||||
|
|||||||
101
lib/main.dart
101
lib/main.dart
@@ -21,6 +21,8 @@ import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
|||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
|
import 'package:paperless_mobile/core/factory/paperless_api_factory_impl.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
@@ -89,10 +91,8 @@ void main() async {
|
|||||||
iosInfo = await DeviceInfoPlugin().iosInfo;
|
iosInfo = await DeviceInfoPlugin().iosInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize External dependencies
|
|
||||||
final connectivity = Connectivity();
|
final connectivity = Connectivity();
|
||||||
final localAuthentication = LocalAuthentication();
|
final localAuthentication = LocalAuthentication();
|
||||||
// Initialize other utility classes
|
|
||||||
final connectivityStatusService = ConnectivityStatusServiceImpl(connectivity);
|
final connectivityStatusService = ConnectivityStatusServiceImpl(connectivity);
|
||||||
final localAuthService = LocalAuthenticationService(localAuthentication);
|
final localAuthService = LocalAuthenticationService(localAuthentication);
|
||||||
|
|
||||||
@@ -111,40 +111,12 @@ void main() async {
|
|||||||
languageHeaderInterceptor,
|
languageHeaderInterceptor,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Initialize Paperless APIs
|
|
||||||
final authApi = PaperlessAuthenticationApiImpl(sessionManager.client);
|
|
||||||
final documentsApi = PaperlessDocumentsApiImpl(sessionManager.client);
|
|
||||||
final labelsApi = PaperlessLabelApiImpl(sessionManager.client);
|
|
||||||
final statsApi = PaperlessServerStatsApiImpl(sessionManager.client);
|
|
||||||
final savedViewsApi = PaperlessSavedViewsApiImpl(sessionManager.client);
|
|
||||||
final tasksApi = PaperlessTasksApiImpl(
|
|
||||||
sessionManager.client,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Initialize Blocs/Cubits
|
// Initialize Blocs/Cubits
|
||||||
final connectivityCubit = ConnectivityCubit(connectivityStatusService);
|
final connectivityCubit = ConnectivityCubit(connectivityStatusService);
|
||||||
|
|
||||||
// Load application settings and stored authentication data
|
// Load application settings and stored authentication data
|
||||||
await connectivityCubit.initialize();
|
await connectivityCubit.initialize();
|
||||||
|
|
||||||
// Create repositories
|
|
||||||
final labelRepository = LabelRepository(labelsApi);
|
|
||||||
final savedViewRepository = SavedViewRepository(savedViewsApi);
|
|
||||||
|
|
||||||
//Create cubits/blocs
|
|
||||||
final authCubit = AuthenticationCubit(
|
|
||||||
localAuthService,
|
|
||||||
authApi,
|
|
||||||
sessionManager,
|
|
||||||
labelRepository,
|
|
||||||
savedViewRepository,
|
|
||||||
statsApi,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (globalSettings.currentLoggedInUser != null) {
|
|
||||||
await authCubit.restoreSessionState();
|
|
||||||
}
|
|
||||||
|
|
||||||
final localNotificationService = LocalNotificationService();
|
final localNotificationService = LocalNotificationService();
|
||||||
await localNotificationService.initialize();
|
await localNotificationService.initialize();
|
||||||
|
|
||||||
@@ -156,42 +128,20 @@ void main() async {
|
|||||||
runApp(
|
runApp(
|
||||||
MultiProvider(
|
MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
ChangeNotifierProvider.value(value: sessionManager),
|
||||||
Provider<LocalAuthenticationService>.value(value: localAuthService),
|
Provider<LocalAuthenticationService>.value(value: localAuthService),
|
||||||
Provider<PaperlessAuthenticationApi>.value(value: authApi),
|
|
||||||
Provider<PaperlessDocumentsApi>.value(value: documentsApi),
|
|
||||||
Provider<PaperlessLabelsApi>.value(value: labelsApi),
|
|
||||||
Provider<PaperlessServerStatsApi>.value(value: statsApi),
|
|
||||||
Provider<PaperlessSavedViewsApi>.value(value: savedViewsApi),
|
|
||||||
Provider<PaperlessTasksApi>.value(value: tasksApi),
|
|
||||||
Provider<cm.CacheManager>(
|
|
||||||
create: (context) => cm.CacheManager(
|
|
||||||
cm.Config(
|
|
||||||
'cacheKey',
|
|
||||||
fileService: DioFileService(sessionManager.client),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Provider<ConnectivityStatusService>.value(
|
Provider<ConnectivityStatusService>.value(
|
||||||
value: connectivityStatusService,
|
value: connectivityStatusService,
|
||||||
),
|
),
|
||||||
Provider<LocalNotificationService>.value(value: localNotificationService),
|
Provider<LocalNotificationService>.value(value: localNotificationService),
|
||||||
Provider.value(value: DocumentChangedNotifier()),
|
Provider.value(value: DocumentChangedNotifier()),
|
||||||
],
|
],
|
||||||
child: MultiRepositoryProvider(
|
child: MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
RepositoryProvider<LabelRepository>.value(
|
BlocProvider<ConnectivityCubit>.value(value: connectivityCubit),
|
||||||
value: labelRepository,
|
|
||||||
),
|
|
||||||
RepositoryProvider<SavedViewRepository>.value(
|
|
||||||
value: savedViewRepository,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
child: MultiBlocProvider(
|
child: PaperlessMobileEntrypoint(
|
||||||
providers: [
|
paperlessProviderFactory: PaperlessApiFactoryImpl(sessionManager),
|
||||||
BlocProvider<AuthenticationCubit>.value(value: authCubit),
|
|
||||||
BlocProvider<ConnectivityCubit>.value(value: connectivityCubit),
|
|
||||||
],
|
|
||||||
child: const PaperlessMobileEntrypoint(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -199,8 +149,10 @@ void main() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PaperlessMobileEntrypoint extends StatefulWidget {
|
class PaperlessMobileEntrypoint extends StatefulWidget {
|
||||||
|
final PaperlessApiFactory paperlessProviderFactory;
|
||||||
const PaperlessMobileEntrypoint({
|
const PaperlessMobileEntrypoint({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
required this.paperlessProviderFactory,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -238,7 +190,9 @@ class _PaperlessMobileEntrypointState extends State<PaperlessMobileEntrypoint> {
|
|||||||
routes: {
|
routes: {
|
||||||
DocumentDetailsRoute.routeName: (context) => const DocumentDetailsRoute(),
|
DocumentDetailsRoute.routeName: (context) => const DocumentDetailsRoute(),
|
||||||
},
|
},
|
||||||
home: const AuthenticationWrapper(),
|
home: AuthenticationWrapper(
|
||||||
|
paperlessProviderFactory: widget.paperlessProviderFactory,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -248,7 +202,12 @@ class _PaperlessMobileEntrypointState extends State<PaperlessMobileEntrypoint> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AuthenticationWrapper extends StatefulWidget {
|
class AuthenticationWrapper extends StatefulWidget {
|
||||||
const AuthenticationWrapper({Key? key}) : super(key: key);
|
final PaperlessApiFactory paperlessProviderFactory;
|
||||||
|
|
||||||
|
const AuthenticationWrapper({
|
||||||
|
Key? key,
|
||||||
|
required this.paperlessProviderFactory,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AuthenticationWrapper> createState() => _AuthenticationWrapperState();
|
State<AuthenticationWrapper> createState() => _AuthenticationWrapperState();
|
||||||
@@ -295,17 +254,19 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<AuthenticationCubit, AuthenticationState>(
|
return BlocBuilder<AuthenticationCubit, AuthenticationState>(
|
||||||
builder: (context, authentication) {
|
builder: (context, authentication) {
|
||||||
if (authentication.isAuthenticated) {
|
return authentication.when(
|
||||||
return HomeRoute(
|
unauthenticated: () => LoginPage(
|
||||||
key: ValueKey(authentication.localUserId),
|
titleString: S.of(context)!.connectToPaperless,
|
||||||
);
|
submitText: S.of(context)!.signIn,
|
||||||
} else if (authentication.showBiometricAuthenticationScreen) {
|
onSubmit: _onLogin,
|
||||||
return const VerifyIdentityPage();
|
),
|
||||||
}
|
requriresLocalAuthentication: () => const VerifyIdentityPage(),
|
||||||
return LoginPage(
|
authenticated: (localUserId, apiVersion) => HomeRoute(
|
||||||
titleString: S.of(context)!.connectToPaperless,
|
key: ValueKey(localUserId),
|
||||||
submitText: S.of(context)!.signIn,
|
paperlessApiVersion: apiVersion,
|
||||||
onSubmit: _onLogin,
|
paperlessProviderFactory: widget.paperlessProviderFactory,
|
||||||
|
localUserId: localUserId,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user