From 06df2b764937d3f312e9599ea85963f80ec640ca Mon Sep 17 00:00:00 2001 From: Freek van de Ven Date: Thu, 7 Dec 2023 06:03:02 +0100 Subject: [PATCH] feat: add more methods to the timeline interface --- .../service/firebase_timeline_service.dart | 81 +++++++++++++++++++ .../lib/src/services/timeline_service.dart | 2 + 2 files changed, 83 insertions(+) diff --git a/packages/flutter_timeline_firebase/lib/src/service/firebase_timeline_service.dart b/packages/flutter_timeline_firebase/lib/src/service/firebase_timeline_service.dart index 0bcbaf2..07047ad 100644 --- a/packages/flutter_timeline_firebase/lib/src/service/firebase_timeline_service.dart +++ b/packages/flutter_timeline_firebase/lib/src/service/firebase_timeline_service.dart @@ -122,6 +122,50 @@ class FirebaseTimelineService with ChangeNotifier implements TimelineService { return posts; } + @override + Future> fetchPostsPaginated( + String? category, + int limit, + ) async { + // only take posts that are in our category + var oldestPost = _posts + .where( + (element) => category == null || element.category == category, + ) + .fold( + _posts.first, + (previousValue, element) => + (previousValue.createdAt.isBefore(element.createdAt)) + ? previousValue + : element, + ); + var snapshot = (category != null) + ? await _db + .collection(_options.timelineCollectionName) + .where('category', isEqualTo: category) + .orderBy('created_at', descending: true) + .startAfter([oldestPost]) + .limit(limit) + .get() + : await _db + .collection(_options.timelineCollectionName) + .orderBy('created_at', descending: true) + .startAfter([oldestPost.createdAt]) + .limit(limit) + .get(); + // add the new posts to the list + var posts = []; + for (var doc in snapshot.docs) { + var data = doc.data(); + var user = await _userService.getUser(data['creator_id']); + var post = TimelinePost.fromJson(doc.id, data).copyWith(creator: user); + posts.add(post); + } + _posts = [..._posts, ...posts]; + notifyListeners(); + return posts; + } + @override Future fetchPost(TimelinePost post) async { var doc = await _db @@ -139,6 +183,43 @@ class FirebaseTimelineService with ChangeNotifier implements TimelineService { return updatedPost; } + @override + Future> refreshPosts(String? category) async { + // fetch all posts between now and the newest posts we have + var newestPostWeHave = _posts + .where( + (element) => category == null || element.category == category, + ) + .fold( + _posts.first, + (previousValue, element) => + (previousValue.createdAt.isAfter(element.createdAt)) + ? previousValue + : element, + ); + var snapshot = (category != null) + ? await _db + .collection(_options.timelineCollectionName) + .where('category', isEqualTo: category) + .orderBy('created_at', descending: true) + .endBefore([newestPostWeHave.createdAt]).get() + : await _db + .collection(_options.timelineCollectionName) + .orderBy('created_at', descending: true) + .endBefore([newestPostWeHave.createdAt]).get(); + // add the new posts to the list + var posts = []; + for (var doc in snapshot.docs) { + var data = doc.data(); + var user = await _userService.getUser(data['creator_id']); + var post = TimelinePost.fromJson(doc.id, data).copyWith(creator: user); + posts.add(post); + } + _posts = [...posts, ..._posts]; + notifyListeners(); + return posts; + } + @override TimelinePost? getPost(String postId) => (_posts.any((element) => element.id == postId)) diff --git a/packages/flutter_timeline_interface/lib/src/services/timeline_service.dart b/packages/flutter_timeline_interface/lib/src/services/timeline_service.dart index 2f7e843..d872eb2 100644 --- a/packages/flutter_timeline_interface/lib/src/services/timeline_service.dart +++ b/packages/flutter_timeline_interface/lib/src/services/timeline_service.dart @@ -14,8 +14,10 @@ abstract class TimelineService with ChangeNotifier { Future createPost(TimelinePost post); Future> fetchPosts(String? category); Future fetchPost(TimelinePost post); + Future> fetchPostsPaginated(String? category, int limit); TimelinePost? getPost(String postId); List getPosts(String? category); + Future> refreshPosts(String? category); Future fetchPostDetails(TimelinePost post); Future reactToPost( TimelinePost post,