chore: improve home screen performance

This commit is contained in:
Kingkor Roy Tirtho 2025-02-23 09:55:46 +06:00
parent e8e2d78529
commit 47edb8bf96
5 changed files with 52 additions and 89 deletions

View File

@ -52,7 +52,11 @@ class PlaybuttonCard extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: context.theme.borderRadiusMd,
image: DecorationImage(
image: UniversalImage.imageProvider(imageUrl!),
image: UniversalImage.imageProvider(
imageUrl!,
height: 200 * scale,
width: 200 * scale,
),
fit: BoxFit.cover,
),
),

View File

@ -1,6 +1,5 @@
import 'dart:ui';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
@ -8,8 +7,6 @@ import 'package:skeletonizer/skeletonizer.dart';
import 'package:spotube/collections/fake.dart';
import 'package:spotube/modules/home/sections/friends/friend_item.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/utils/use_breakpoint_value.dart';
import 'package:spotube/models/spotify_friends.dart';
import 'package:spotube/provider/authentication/authentication.dart';
import 'package:spotube/provider/spotify/spotify.dart';
@ -23,90 +20,46 @@ class HomePageFriendsSection extends HookConsumerWidget {
final friends =
friendsQuery.asData?.value.friends ?? FakeData.friends.friends;
final groupCount = useBreakpointValue(
sm: 3,
xs: 2,
md: 4,
lg: 5,
xl: 6,
xxl: 7,
);
final friendGroup = useMemoized(
() => friends.fold<List<List<SpotifyFriendActivity>>>(
[],
(previousValue, element) {
if (previousValue.isEmpty) {
return [
[element]
];
}
final lastGroup = previousValue.last;
if (lastGroup.length < groupCount) {
return [
...previousValue.sublist(0, previousValue.length - 1),
[...lastGroup, element]
];
}
return [
...previousValue,
[element]
];
},
),
[friends, groupCount],
);
if (friendsQuery.isLoading ||
friendsQuery.asData?.value.friends.isEmpty == true ||
auth.asData?.value == null) {
return const SliverToBoxAdapter(
child: SizedBox.shrink(),
);
return const SizedBox.shrink();
}
return Skeletonizer.sliver(
enabled: friendsQuery.isLoading,
child: SliverMainAxisGroup(
slivers: [
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
context.l10n.friends,
style: context.theme.typography.h4,
),
),
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
context.l10n.friends,
style: context.theme.typography.h4,
),
SliverToBoxAdapter(
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
dragDevices: PointerDeviceKind.values.toSet(),
),
child: SingleChildScrollView(
),
SizedBox(
height: 80 * context.theme.scaling,
width: double.infinity,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
dragDevices: PointerDeviceKind.values.toSet(),
scrollbars: false,
),
child: Skeletonizer(
enabled: friendsQuery.isLoading,
child: ListView.separated(
padding: const EdgeInsets.symmetric(horizontal: 8),
scrollDirection: Axis.horizontal,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (final group in friendGroup)
Row(
children: [
for (final friend in group)
Padding(
padding: const EdgeInsets.all(8.0),
child: FriendItem(friend: friend),
),
],
),
],
),
itemCount: friends.length,
separatorBuilder: (context, index) => const Gap(8),
itemBuilder: (context, index) {
return FriendItem(friend: friends[index]);
},
),
),
),
],
),
),
],
);
}
}

View File

@ -35,7 +35,8 @@ class HomeGenresSection extends HookConsumerWidget {
);
final controller = useMemoized(() => CarouselController(), []);
return SliverList.list(
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),

View File

@ -6,7 +6,6 @@ import 'package:spotify/spotify.dart' hide Offset, Image;
import 'package:spotube/collections/env.dart';
import 'package:spotube/collections/routes.gr.dart';
import 'package:spotube/components/dialogs/select_device_dialog.dart';
import 'package:spotube/components/image/universal_image.dart';
import 'package:spotube/components/playbutton_view/playbutton_card.dart';
import 'package:spotube/components/playbutton_view/playbutton_tile.dart';
import 'package:spotube/extensions/context.dart';
@ -200,16 +199,14 @@ class PlaylistCard extends HookConsumerWidget {
);
},
)
: UniversalImage(
path: imageUrl,
fit: BoxFit.cover,
);
: null;
if (_isTile) {
return PlaybuttonTile(
title: playlist.name!,
description: playlist.description,
image: image,
imageUrl: image == null ? imageUrl : null,
isPlaying: isPlaylistPlaying,
isLoading: isLoading,
isOwner: isOwner,
@ -223,6 +220,7 @@ class PlaylistCard extends HookConsumerWidget {
title: playlist.name!,
description: playlist.description,
image: image,
imageUrl: image == null ? imageUrl : null,
isPlaying: isPlaylistPlaying,
isLoading: isLoading,
isOwner: isOwner,

View File

@ -62,12 +62,19 @@ class HomePage extends HookConsumerWidget {
)
else if (kIsMacOS)
const SliverGap(10),
const HomeGenresSection(),
const SliverGap(10),
const SliverToBoxAdapter(child: HomeRecentlyPlayedSection()),
const SliverToBoxAdapter(child: HomeFeaturedSection()),
const HomePageFriendsSection(),
const SliverToBoxAdapter(child: HomeNewReleasesSection()),
SliverList.builder(
itemCount: 5,
itemBuilder: (context, index) {
return switch (index) {
0 => const HomeGenresSection(),
1 => const HomeRecentlyPlayedSection(),
2 => const HomeFeaturedSection(),
3 => const HomePageFriendsSection(),
_ => const HomeNewReleasesSection()
};
},
),
const HomePageFeedSection(),
const SliverSafeArea(sliver: HomeMadeForUserSection()),
],