mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
chore: improve home screen performance
This commit is contained in:
parent
e8e2d78529
commit
47edb8bf96
@ -52,7 +52,11 @@ class PlaybuttonCard extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: context.theme.borderRadiusMd,
|
borderRadius: context.theme.borderRadiusMd,
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: UniversalImage.imageProvider(imageUrl!),
|
image: UniversalImage.imageProvider(
|
||||||
|
imageUrl!,
|
||||||
|
height: 200 * scale,
|
||||||
|
width: 200 * scale,
|
||||||
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||||
import 'package:shadcn_flutter/shadcn_flutter_extension.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/collections/fake.dart';
|
||||||
import 'package:spotube/modules/home/sections/friends/friend_item.dart';
|
import 'package:spotube/modules/home/sections/friends/friend_item.dart';
|
||||||
import 'package:spotube/extensions/context.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/authentication/authentication.dart';
|
||||||
import 'package:spotube/provider/spotify/spotify.dart';
|
import 'package:spotube/provider/spotify/spotify.dart';
|
||||||
|
|
||||||
@ -23,90 +20,46 @@ class HomePageFriendsSection extends HookConsumerWidget {
|
|||||||
final friends =
|
final friends =
|
||||||
friendsQuery.asData?.value.friends ?? FakeData.friends.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 ||
|
if (friendsQuery.isLoading ||
|
||||||
friendsQuery.asData?.value.friends.isEmpty == true ||
|
friendsQuery.asData?.value.friends.isEmpty == true ||
|
||||||
auth.asData?.value == null) {
|
auth.asData?.value == null) {
|
||||||
return const SliverToBoxAdapter(
|
return const SizedBox.shrink();
|
||||||
child: SizedBox.shrink(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Skeletonizer.sliver(
|
return Column(
|
||||||
enabled: friendsQuery.isLoading,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: SliverMainAxisGroup(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
slivers: [
|
children: [
|
||||||
SliverToBoxAdapter(
|
Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.all(8.0),
|
||||||
padding: const EdgeInsets.all(8.0),
|
child: Text(
|
||||||
child: Text(
|
context.l10n.friends,
|
||||||
context.l10n.friends,
|
style: context.theme.typography.h4,
|
||||||
style: context.theme.typography.h4,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SliverToBoxAdapter(
|
),
|
||||||
child: ScrollConfiguration(
|
SizedBox(
|
||||||
behavior: ScrollConfiguration.of(context).copyWith(
|
height: 80 * context.theme.scaling,
|
||||||
dragDevices: PointerDeviceKind.values.toSet(),
|
width: double.infinity,
|
||||||
),
|
child: ScrollConfiguration(
|
||||||
child: SingleChildScrollView(
|
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,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Column(
|
itemCount: friends.length,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
separatorBuilder: (context, index) => const Gap(8),
|
||||||
children: [
|
itemBuilder: (context, index) {
|
||||||
for (final group in friendGroup)
|
return FriendItem(friend: friends[index]);
|
||||||
Row(
|
},
|
||||||
children: [
|
|
||||||
for (final friend in group)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: FriendItem(friend: friend),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,8 @@ class HomeGenresSection extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
final controller = useMemoized(() => CarouselController(), []);
|
final controller = useMemoized(() => CarouselController(), []);
|
||||||
|
|
||||||
return SliverList.list(
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
@ -6,7 +6,6 @@ import 'package:spotify/spotify.dart' hide Offset, Image;
|
|||||||
import 'package:spotube/collections/env.dart';
|
import 'package:spotube/collections/env.dart';
|
||||||
import 'package:spotube/collections/routes.gr.dart';
|
import 'package:spotube/collections/routes.gr.dart';
|
||||||
import 'package:spotube/components/dialogs/select_device_dialog.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_card.dart';
|
||||||
import 'package:spotube/components/playbutton_view/playbutton_tile.dart';
|
import 'package:spotube/components/playbutton_view/playbutton_tile.dart';
|
||||||
import 'package:spotube/extensions/context.dart';
|
import 'package:spotube/extensions/context.dart';
|
||||||
@ -200,16 +199,14 @@ class PlaylistCard extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: UniversalImage(
|
: null;
|
||||||
path: imageUrl,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (_isTile) {
|
if (_isTile) {
|
||||||
return PlaybuttonTile(
|
return PlaybuttonTile(
|
||||||
title: playlist.name!,
|
title: playlist.name!,
|
||||||
description: playlist.description,
|
description: playlist.description,
|
||||||
image: image,
|
image: image,
|
||||||
|
imageUrl: image == null ? imageUrl : null,
|
||||||
isPlaying: isPlaylistPlaying,
|
isPlaying: isPlaylistPlaying,
|
||||||
isLoading: isLoading,
|
isLoading: isLoading,
|
||||||
isOwner: isOwner,
|
isOwner: isOwner,
|
||||||
@ -223,6 +220,7 @@ class PlaylistCard extends HookConsumerWidget {
|
|||||||
title: playlist.name!,
|
title: playlist.name!,
|
||||||
description: playlist.description,
|
description: playlist.description,
|
||||||
image: image,
|
image: image,
|
||||||
|
imageUrl: image == null ? imageUrl : null,
|
||||||
isPlaying: isPlaylistPlaying,
|
isPlaying: isPlaylistPlaying,
|
||||||
isLoading: isLoading,
|
isLoading: isLoading,
|
||||||
isOwner: isOwner,
|
isOwner: isOwner,
|
||||||
|
@ -62,12 +62,19 @@ class HomePage extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
else if (kIsMacOS)
|
else if (kIsMacOS)
|
||||||
const SliverGap(10),
|
const SliverGap(10),
|
||||||
const HomeGenresSection(),
|
|
||||||
const SliverGap(10),
|
const SliverGap(10),
|
||||||
const SliverToBoxAdapter(child: HomeRecentlyPlayedSection()),
|
SliverList.builder(
|
||||||
const SliverToBoxAdapter(child: HomeFeaturedSection()),
|
itemCount: 5,
|
||||||
const HomePageFriendsSection(),
|
itemBuilder: (context, index) {
|
||||||
const SliverToBoxAdapter(child: HomeNewReleasesSection()),
|
return switch (index) {
|
||||||
|
0 => const HomeGenresSection(),
|
||||||
|
1 => const HomeRecentlyPlayedSection(),
|
||||||
|
2 => const HomeFeaturedSection(),
|
||||||
|
3 => const HomePageFriendsSection(),
|
||||||
|
_ => const HomeNewReleasesSection()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
),
|
||||||
const HomePageFeedSection(),
|
const HomePageFeedSection(),
|
||||||
const SliverSafeArea(sliver: HomeMadeForUserSection()),
|
const SliverSafeArea(sliver: HomeMadeForUserSection()),
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user