💄 Optimize skeleton effect

This commit is contained in:
2025-12-06 19:01:40 +08:00
parent dff84dde58
commit e4cd0c99df
4 changed files with 88 additions and 33 deletions

View File

@@ -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),
);
}
}

View File

@@ -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),
],
),
);
}
}

View File

@@ -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),