💄 Optimize skeleton effect
This commit is contained in:
@@ -40,8 +40,23 @@ class PaginationList<T> extends HookConsumerWidget {
|
||||
final noti = ref.watch(notifier);
|
||||
|
||||
if ((data.isLoading || noti.isLoading) && data.value?.isEmpty == true) {
|
||||
final content = ResponseLoadingWidget();
|
||||
return isSliver ? SliverFillRemaining(child: content) : content;
|
||||
final content = List<Widget>.generate(
|
||||
10,
|
||||
(_) => Skeletonizer(
|
||||
enabled: true,
|
||||
effect: ShimmerEffect(
|
||||
baseColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
highlightColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.surfaceContainerHighest,
|
||||
),
|
||||
containersColor: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
child: footerSkeletonChild ?? const _DefaultSkeletonChild(),
|
||||
),
|
||||
);
|
||||
return isSliver
|
||||
? SliverList.list(children: content)
|
||||
: ListView(children: content);
|
||||
}
|
||||
|
||||
if (data.hasError) {
|
||||
@@ -116,8 +131,23 @@ class PaginationWidget<T> extends HookConsumerWidget {
|
||||
final noti = ref.watch(notifier);
|
||||
|
||||
if ((data.isLoading || noti.isLoading) && data.value?.isEmpty == true) {
|
||||
final content = ResponseLoadingWidget();
|
||||
return isSliver ? SliverFillRemaining(child: content) : content;
|
||||
final content = List<Widget>.generate(
|
||||
10,
|
||||
(_) => Skeletonizer(
|
||||
enabled: true,
|
||||
effect: ShimmerEffect(
|
||||
baseColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
highlightColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.surfaceContainerHighest,
|
||||
),
|
||||
containersColor: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
child: footerSkeletonChild ?? const _DefaultSkeletonChild(),
|
||||
),
|
||||
);
|
||||
return isSliver
|
||||
? SliverList.list(children: content)
|
||||
: ListView(children: content);
|
||||
}
|
||||
|
||||
if (data.hasError) {
|
||||
@@ -161,13 +191,12 @@ class PaginationListFooter<T> extends HookConsumerWidget {
|
||||
|
||||
final placeholder = Skeletonizer(
|
||||
enabled: true,
|
||||
child:
|
||||
skeletonChild ??
|
||||
ListTile(
|
||||
title: Text('Some data'),
|
||||
subtitle: const Text('Subtitle here'),
|
||||
trailing: const Icon(Icons.ac_unit),
|
||||
),
|
||||
effect: ShimmerEffect(
|
||||
baseColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
highlightColor: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
),
|
||||
containersColor: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
child: skeletonChild ?? _DefaultSkeletonChild(),
|
||||
);
|
||||
final child = hasBeenVisible.value
|
||||
? data.isLoading
|
||||
@@ -194,3 +223,16 @@ class PaginationListFooter<T> extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DefaultSkeletonChild extends StatelessWidget {
|
||||
const _DefaultSkeletonChild();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
title: Text('Some data'),
|
||||
subtitle: const Text('Subtitle here'),
|
||||
trailing: const Icon(Icons.ac_unit),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,28 +26,38 @@ class PostItemSkeleton extends StatelessWidget {
|
||||
final renderingPadding =
|
||||
padding ?? const EdgeInsets.symmetric(horizontal: 8, vertical: 8);
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Gap(renderingPadding.vertical),
|
||||
_PostHeaderSkeleton(
|
||||
isFullPost: isFullPost,
|
||||
isCompact: isCompact,
|
||||
renderingPadding: renderingPadding,
|
||||
return Center(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 640),
|
||||
child: Card(
|
||||
margin: EdgeInsets.only(bottom: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Gap(renderingPadding.vertical),
|
||||
_PostHeaderSkeleton(
|
||||
isFullPost: isFullPost,
|
||||
isCompact: isCompact,
|
||||
renderingPadding: renderingPadding,
|
||||
),
|
||||
_PostBodySkeleton(
|
||||
isFullPost: isFullPost,
|
||||
renderingPadding: renderingPadding,
|
||||
),
|
||||
if (isShowReference)
|
||||
_ReferencedPostWidgetSkeleton(
|
||||
renderingPadding: renderingPadding,
|
||||
),
|
||||
if (isEmbedReply)
|
||||
_PostReplyPreviewSkeleton(
|
||||
renderingPadding: renderingPadding,
|
||||
).padding(horizontal: renderingPadding.horizontal, top: 8),
|
||||
Gap(renderingPadding.vertical),
|
||||
],
|
||||
),
|
||||
),
|
||||
_PostBodySkeleton(
|
||||
isFullPost: isFullPost,
|
||||
renderingPadding: renderingPadding,
|
||||
),
|
||||
if (isShowReference)
|
||||
_ReferencedPostWidgetSkeleton(renderingPadding: renderingPadding),
|
||||
if (isEmbedReply)
|
||||
_PostReplyPreviewSkeleton(
|
||||
renderingPadding: renderingPadding,
|
||||
).padding(horizontal: renderingPadding.horizontal, top: 8),
|
||||
Gap(renderingPadding.vertical),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:island/pods/network.dart';
|
||||
import 'package:island/pods/paging.dart';
|
||||
import 'package:island/widgets/paging/pagination_list.dart';
|
||||
import 'package:island/widgets/post/post_item.dart';
|
||||
import 'package:island/widgets/post/post_item_skeleton.dart';
|
||||
|
||||
final postRepliesProvider = AsyncNotifierProvider.autoDispose.family(
|
||||
PostRepliesNotifier.new,
|
||||
@@ -52,6 +53,7 @@ class PostRepliesList extends HookConsumerWidget {
|
||||
notifier: provider.notifier,
|
||||
isRefreshable: false,
|
||||
isSliver: true,
|
||||
footerSkeletonChild: const PostItemSkeleton(),
|
||||
itemBuilder: (context, index, item) {
|
||||
final contentWidget = Card(
|
||||
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
|
||||
Reference in New Issue
Block a user