Add deduplication
This commit is contained in:
parent
4519077ae2
commit
948fff79f3
|
@ -36,7 +36,7 @@ class CommunitiesListPage extends StatelessWidget {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
uniqueProp: (item) => item.community.id,
|
uniqueProp: (item) => item.community.actorId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue