mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-16 12:12:30 -06:00
Cleaned up code, implemented message queue to notify subscribers of document updates.
This commit is contained in:
@@ -1,23 +1,20 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
import 'package:paperless_api/paperless_api.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/state/impl/correspondent_repository_state.dart';
|
||||
import 'package:paperless_mobile/core/repository/state/impl/document_type_repository_state.dart';
|
||||
import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
|
||||
import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart';
|
||||
import 'package:paperless_mobile/features/paged_document_view/paged_documents_mixin.dart';
|
||||
|
||||
class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
final LabelRepository<Tag, TagRepositoryState> _tagsRepository;
|
||||
final LabelRepository<Correspondent, CorrespondentRepositoryState>
|
||||
_correspondentRepository;
|
||||
final LabelRepository<DocumentType, DocumentTypeRepositoryState>
|
||||
_documentTypeRepository;
|
||||
final LabelRepository<Tag> _tagsRepository;
|
||||
final LabelRepository<Correspondent> _correspondentRepository;
|
||||
final LabelRepository<DocumentType> _documentTypeRepository;
|
||||
|
||||
final PaperlessDocumentsApi _documentsApi;
|
||||
|
||||
@override
|
||||
final DocumentChangedNotifier notifier;
|
||||
|
||||
@@ -28,7 +25,6 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
@override
|
||||
PaperlessDocumentsApi get api => _documentsApi;
|
||||
|
||||
Timer? _taskTimer;
|
||||
InboxCubit(
|
||||
this._tagsRepository,
|
||||
this._documentsApi,
|
||||
@@ -45,11 +41,20 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
availableTags: _tagsRepository.current?.values ?? {},
|
||||
),
|
||||
) {
|
||||
_subscriptions.addAll(
|
||||
notifier.listen(
|
||||
onDeleted: remove,
|
||||
onUpdated: replace,
|
||||
),
|
||||
notifier.subscribe(
|
||||
this,
|
||||
onDeleted: remove,
|
||||
onUpdated: (document) {
|
||||
if (document.tags
|
||||
.toSet()
|
||||
.intersection(state.inboxTags.toSet())
|
||||
.isEmpty) {
|
||||
remove(document);
|
||||
emit(state.copyWith(itemsInInboxCount: state.itemsInInboxCount - 1));
|
||||
} else {
|
||||
replace(document);
|
||||
}
|
||||
},
|
||||
);
|
||||
_subscriptions.add(
|
||||
_tagsRepository.values.listen((event) {
|
||||
@@ -74,21 +79,35 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
}
|
||||
}),
|
||||
);
|
||||
//TODO: Do this properly in a background task.
|
||||
_taskTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
|
||||
|
||||
refreshItemsInInboxCount(false);
|
||||
loadInbox();
|
||||
|
||||
Timer.periodic(const Duration(seconds: 5), (timer) {
|
||||
if (isClosed) {
|
||||
timer.cancel();
|
||||
}
|
||||
refreshItemsInInboxCount();
|
||||
});
|
||||
}
|
||||
|
||||
void refreshItemsInInboxCount() async {
|
||||
void refreshItemsInInboxCount([bool shouldLoadInbox = true]) async {
|
||||
final stats = await _statsApi.getServerStatistics();
|
||||
emit(state.copyWith(itemsInInboxCount: stats.documentsInInbox));
|
||||
|
||||
if (stats.documentsInInbox != state.itemsInInboxCount && shouldLoadInbox) {
|
||||
loadInbox();
|
||||
}
|
||||
emit(
|
||||
state.copyWith(
|
||||
itemsInInboxCount: stats.documentsInInbox,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Fetches inbox tag ids and loads the inbox items (documents).
|
||||
///
|
||||
Future<void> initializeInbox() async {
|
||||
Future<void> loadInbox() async {
|
||||
final inboxTags = await _tagsRepository.findAll().then(
|
||||
(tags) => tags.where((t) => t.isInboxTag ?? false).map((t) => t.id!),
|
||||
);
|
||||
@@ -104,7 +123,7 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
);
|
||||
}
|
||||
emit(state.copyWith(inboxTags: inboxTags));
|
||||
return updateFilter(
|
||||
updateFilter(
|
||||
filter: DocumentFilter(
|
||||
sortField: SortField.added,
|
||||
tags: IdsTagsQuery.fromIds(inboxTags),
|
||||
@@ -121,11 +140,12 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
document.tags.toSet().intersection(state.inboxTags.toSet());
|
||||
|
||||
final updatedTags = {...document.tags}..removeAll(tagsToRemove);
|
||||
await api.update(
|
||||
final updatedDocument = await api.update(
|
||||
document.copyWith(tags: updatedTags),
|
||||
);
|
||||
await remove(document);
|
||||
emit(state.copyWith(itemsInInboxCount: state.itemsInInboxCount - 1));
|
||||
// Remove first so document is not replaced first.
|
||||
remove(document);
|
||||
notifier.notifyUpdated(updatedDocument);
|
||||
return tagsToRemove;
|
||||
}
|
||||
|
||||
@@ -136,10 +156,12 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
DocumentModel document,
|
||||
Iterable<int> removedTags,
|
||||
) async {
|
||||
final updatedDoc = document.copyWith(
|
||||
tags: {...document.tags, ...removedTags},
|
||||
final updatedDocument = await _documentsApi.update(
|
||||
document.copyWith(
|
||||
tags: {...document.tags, ...removedTags},
|
||||
),
|
||||
);
|
||||
await _documentsApi.update(updatedDoc);
|
||||
notifier.notifyUpdated(updatedDocument);
|
||||
emit(state.copyWith(itemsInInboxCount: state.itemsInInboxCount + 1));
|
||||
return reload();
|
||||
}
|
||||
@@ -166,22 +188,12 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
}
|
||||
}
|
||||
|
||||
void replaceUpdatedDocument(DocumentModel document) {
|
||||
if (document.tags.any((id) => state.inboxTags.contains(id))) {
|
||||
// If replaced document still has inbox tag assigned:
|
||||
replace(document);
|
||||
} else {
|
||||
// Remove document from inbox.
|
||||
remove(document);
|
||||
emit(state.copyWith(itemsInInboxCount: state.itemsInInboxCount - 1));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> assignAsn(DocumentModel document) async {
|
||||
if (document.archiveSerialNumber == null) {
|
||||
final int asn = await _documentsApi.findNextAsn();
|
||||
final updatedDocument = await _documentsApi
|
||||
.update(document.copyWith(archiveSerialNumber: asn));
|
||||
|
||||
replace(updatedDocument);
|
||||
}
|
||||
}
|
||||
@@ -202,7 +214,6 @@ class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_taskTimer?.cancel();
|
||||
for (var sub in _subscriptions) {
|
||||
sub.cancel();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ import 'package:paperless_mobile/features/paged_document_view/model/paged_docume
|
||||
|
||||
part 'inbox_state.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
ignoreUnannotated: true,
|
||||
)
|
||||
@JsonSerializable(ignoreUnannotated: true)
|
||||
class InboxState extends PagedDocumentsState {
|
||||
final Iterable<int> inboxTags;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user