Add deduplication

This commit is contained in:
shilangyu 2021-04-22 21:08:30 +02:00
parent 4519077ae2
commit 948fff79f3
5 changed files with 20 additions and 15 deletions

View File

@ -36,7 +36,7 @@ class CommunitiesListPage extends StatelessWidget {
) )
], ],
), ),
uniqueProp: (item) => item.community.id, uniqueProp: (item) => item.community.actorId,
), ),
); );
} }

View File

@ -120,7 +120,7 @@ class InboxPage extends HookWidget {
canBeMarkedAsRead: true, canBeMarkedAsRead: true,
hideOnRead: unreadOnly.value, hideOnRead: unreadOnly.value,
), ),
uniqueProp: (item) => item.comment.id, uniqueProp: (item) => item.comment.apId,
), ),
SortableInfiniteList<PersonMentionView>( SortableInfiniteList<PersonMentionView>(
noItems: const Text('no mentions'), noItems: const Text('no mentions'),
@ -158,7 +158,7 @@ class InboxPage extends HookWidget {
privateMessageView: mv, privateMessageView: mv,
hideOnRead: unreadOnly.value, hideOnRead: unreadOnly.value,
), ),
uniqueProp: (item) => item.privateMessage.id, uniqueProp: (item) => item.privateMessage.apId,
), ),
], ],
), ),

View File

@ -119,13 +119,13 @@ class _SearchResultsList extends HookWidget {
uniqueProp: (item) { uniqueProp: (item) {
switch (type) { switch (type) {
case SearchType.comments: case SearchType.comments:
return (item as CommentView).comment.id; return (item as CommentView).comment.apId;
case SearchType.communities: case SearchType.communities:
return (item as CommunityView).community.id; return (item as CommunityView).community.actorId;
case SearchType.posts: case SearchType.posts:
return (item as PostView).post.id; return (item as PostView).post.apId;
case SearchType.users: case SearchType.users:
return (item as PersonViewSafe).person.id; return (item as PersonViewSafe).person.actorId;
default: default:
return item; return item;
} }

View File

@ -68,25 +68,30 @@ class InfiniteScroll<T> extends HookWidget {
// holds unique props of the data // holds unique props of the data
final dataSet = useRef(HashSet<Object>()); final dataSet = useRef(HashSet<Object>());
final hasMore = useRef(true); final hasMore = useRef(true);
final page = useRef(1);
final isFetching = useRef(false); final isFetching = useRef(false);
final uniquePropFunc = uniqueProp ?? (e) => e as Object;
useEffect(() { useEffect(() {
if (controller != null) { if (controller != null) {
controller?.clear = () { controller?.clear = () {
data.value = []; data.value = [];
hasMore.current = true; hasMore.current = true;
page.current = 1;
dataSet.current.clear();
}; };
} }
return null; return null;
}, []); }, []);
final page = data.value.length ~/ batchSize + 1;
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async { onRefresh: () async {
data.value = []; data.value = [];
hasMore.current = true; hasMore.current = true;
page.current = 1;
dataSet.current.clear();
await HapticFeedback.mediumImpact(); await HapticFeedback.mediumImpact();
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
@ -116,20 +121,20 @@ class InfiniteScroll<T> extends HookWidget {
// if it's already fetching more, skip // if it's already fetching more, skip
if (!isFetching.current) { if (!isFetching.current) {
isFetching.current = true; isFetching.current = true;
fetcher(page, batchSize).then((incoming) { fetcher(page.current, batchSize).then((incoming) {
// if got less than the batchSize, mark the list as done // if got less than the batchSize, mark the list as done
if (incoming.length < batchSize) { if (incoming.length < batchSize) {
hasMore.current = false; hasMore.current = false;
} }
final newData = incoming.where( final newData = incoming.where(
(e) => !dataSet.current.contains(uniqueProp?.call(e) ?? e), (e) => !dataSet.current.contains(uniquePropFunc(e)),
); );
// append new data // append new data
data.value = [...data.value, ...newData]; data.value = [...data.value, ...newData];
dataSet.current dataSet.current.addAll(newData.map(uniquePropFunc));
.addAll(newData.map(uniqueProp ?? (e) => e as Object)); page.current += 1;
}).whenComplete(() => isFetching.current = false); }).whenComplete(() => isFetching.current = false);
} }

View File

@ -75,7 +75,7 @@ class InfinitePostList extends SortableInfiniteList<PostView> {
fetcher: fetcher, fetcher: fetcher,
controller: controller, controller: controller,
noItems: const Text('there are no posts'), noItems: const Text('there are no posts'),
uniqueProp: (item) => item.post.id, uniqueProp: (item) => item.post.apId,
); );
} }
@ -91,6 +91,6 @@ class InfiniteCommentList extends SortableInfiniteList<CommentView> {
fetcher: fetcher, fetcher: fetcher,
controller: controller, controller: controller,
noItems: const Text('there are no comments'), noItems: const Text('there are no comments'),
uniqueProp: (item) => item.comment.id, uniqueProp: (item) => item.comment.apId,
); );
} }