Skip to content

Commit

Permalink
feat: initial platform_ui integration
Browse files Browse the repository at this point in the history
What's changed:
- Sidebar
- Settings
- UserLibrary (root)
- Search (search field)
  • Loading branch information
KRTirtho committed Oct 29, 2022
1 parent 4b21cc8 commit 9eee573
Show file tree
Hide file tree
Showing 22 changed files with 443 additions and 342 deletions.
18 changes: 7 additions & 11 deletions lib/components/Home/Shell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,13 @@ class Shell extends HookConsumerWidget {
)
: null,
extendBodyBehindAppBar: true,
body: Row(
children: [
Sidebar(
selectedIndex: index.value,
onSelectedIndexChanged: (selectedIndex) {
index.value = selectedIndex;
GoRouter.of(context).go(_path[selectedIndex]!);
},
),
Expanded(child: child),
],
body: Sidebar(
selectedIndex: index.value,
onSelectedIndexChanged: (i) {
index.value = i;
GoRouter.of(context).go(_path[index.value]!);
},
child: child,
),
extendBody: true,
bottomNavigationBar: Column(
Expand Down
258 changes: 132 additions & 126 deletions lib/components/Home/Sidebar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:spotube/components/Shared/UniversalImage.dart';
import 'package:spotube/hooks/useBreakpoints.dart';
import 'package:spotube/models/sideBarTiles.dart';
Expand All @@ -15,16 +16,19 @@ import 'package:spotube/provider/SpotifyRequests.dart';
import 'package:spotube/provider/UserPreferences.dart';
import 'package:spotube/utils/platform.dart';
import 'package:spotube/utils/type_conversion_utils.dart';
import 'package:fluent_ui/fluent_ui.dart' as FluentUI;

final sidebarExtendedStateProvider = StateProvider<bool?>((ref) => null);

class Sidebar extends HookConsumerWidget {
final int selectedIndex;
final void Function(int) onSelectedIndexChanged;
final Widget child;

const Sidebar({
required this.selectedIndex,
required this.onSelectedIndexChanged,
required this.child,
Key? key,
}) : super(key: key);

Expand All @@ -45,7 +49,6 @@ class Sidebar extends HookConsumerWidget {
final breakpoints = useBreakpoints();
final extended = useState(false);

final auth = ref.watch(authProvider);
final downloadCount = ref.watch(
downloaderProvider.select((s) => s.currentlyRunning),
);
Expand Down Expand Up @@ -81,10 +84,31 @@ class Sidebar extends HookConsumerWidget {

return SafeArea(
top: false,
child: Material(
color: Theme.of(context).navigationRailTheme.backgroundColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
child: PlatformSidebar(
currentIndex: selectedIndex,
onIndexChanged: onSelectedIndexChanged,
body: Map.fromEntries(
sidebarTileList.map(
(e) {
final icon = Icon(e.icon);
return MapEntry(
PlatformSidebarItem(
icon: icon,
title: Text(
e.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
child,
);
},
),
),
expanded: extended.value,
header: Column(
children: [
if (kIsDesktop)
SizedBox(
Expand Down Expand Up @@ -126,138 +150,120 @@ class Sidebar extends HookConsumerWidget {
],
)
: _buildSmallLogo(),
Expanded(
child: NavigationRail(
destinations: sidebarTileList.map(
(e) {
final icon = Icon(e.icon);
return NavigationRailDestination(
icon: e.title == "Library" && downloadCount > 0
? Badge(
badgeColor: Colors.red[100]!,
badgeContent: Text(
downloadCount.toString(),
style: const TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
animationType: BadgeAnimationType.fade,
child: icon,
)
: icon,
label: Text(
e.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
);
},
).toList(),
selectedIndex: selectedIndex,
onDestinationSelected: onSelectedIndexChanged,
extended: extended.value,
),
),
SizedBox(
width: extended.value ? 256 : 80,
child: HookBuilder(
builder: (context) {
final me = useQuery(
job: currentUserQueryJob,
externalData: ref.watch(spotifyProvider),
);
final data = me.data;
],
),
windowsFooterItems: [
FluentUI.PaneItemAction(
icon: const FluentUI.Icon(FluentUI.FluentIcons.settings),
onTap: () => goToSettings(context),
),
],
footer: SidebarFooter(extended: extended.value),
),
);
}
}

class SidebarFooter extends HookConsumerWidget {
final bool extended;
const SidebarFooter({
Key? key,
required this.extended,
}) : super(key: key);

@override
Widget build(BuildContext context, ref) {
final auth = ref.watch(authProvider);

return SizedBox(
width: extended ? 256 : 80,
child: HookBuilder(
builder: (context) {
final me = useQuery(
job: currentUserQueryJob,
externalData: ref.watch(spotifyProvider),
);
final data = me.data;

final avatarImg = TypeConversionUtils.image_X_UrlString(
data?.images,
index: (data?.images?.length ?? 1) - 1,
placeholder: ImagePlaceholder.artist,
);
final avatarImg = TypeConversionUtils.image_X_UrlString(
data?.images,
index: (data?.images?.length ?? 1) - 1,
placeholder: ImagePlaceholder.artist,
);

useEffect(() {
if (auth.isLoggedIn && !me.hasData) {
me.setExternalData(ref.read(spotifyProvider));
me.refetch();
}
return;
}, [auth.isLoggedIn, me.hasData]);
useEffect(() {
if (auth.isLoggedIn && !me.hasData) {
me.setExternalData(ref.read(spotifyProvider));
me.refetch();
}
return;
}, [auth.isLoggedIn, me.hasData]);

if (extended.value) {
return Padding(
padding: const EdgeInsets.all(16).copyWith(left: 0),
if (extended) {
return Padding(
padding: const EdgeInsets.all(16).copyWith(left: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (auth.isLoggedIn && data == null)
const Center(
child: CircularProgressIndicator(),
)
else if (data != null)
Flexible(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (auth.isLoggedIn && data == null)
const Center(
child: CircularProgressIndicator(),
)
else if (data != null)
Flexible(
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(
avatarImg),
onBackgroundImageError:
(exception, stackTrace) =>
Image.asset(
"assets/user-placeholder.png",
height: 16,
width: 16,
),
),
const SizedBox(
width: 10,
),
Flexible(
child: Text(
data.displayName ?? "Guest",
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(avatarImg),
onBackgroundImageError: (exception, stackTrace) =>
Image.asset(
"assets/user-placeholder.png",
height: 16,
width: 16,
),
),
const SizedBox(
width: 10,
),
Flexible(
child: Text(
data.displayName ?? "Guest",
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
IconButton(
icon: const Icon(Icons.settings_outlined),
onPressed: () => goToSettings(context)),
),
],
));
} else {
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () => goToSettings(context),
child: CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(avatarImg),
onBackgroundImageError: (exception, stackTrace) =>
Image.asset(
"assets/user-placeholder.png",
height: 16,
width: 16,
),
),
),
);
}
},
IconButton(
icon: const Icon(Icons.settings_outlined),
onPressed: () => Sidebar.goToSettings(context)),
],
));
} else {
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () => Sidebar.goToSettings(context),
child: CircleAvatar(
backgroundImage: UniversalImage.imageProvider(avatarImg),
onBackgroundImageError: (exception, stackTrace) =>
Image.asset(
"assets/user-placeholder.png",
height: 16,
width: 16,
),
),
),
)
],
),
);
}
},
),
);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/components/Library/UserDownloads.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/Shared/UniversalImage.dart';
import 'package:spotube/provider/Downloader.dart';
Expand Down Expand Up @@ -47,7 +48,7 @@ class UserDownloads extends HookConsumerWidget {
itemCount: downloader.inQueue.length,
itemBuilder: (context, index) {
final track = downloader.inQueue.elementAt(index);
return ListTile(
return PlatformListTile(
title: Text(track.name!),
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
Expand All @@ -68,7 +69,6 @@ class UserDownloads extends HookConsumerWidget {
height: 30,
child: CircularProgressIndicator.adaptive(),
),
horizontalTitleGap: 5,
subtitle: Text(
TypeConversionUtils.artists_X_String(
track.artists ?? <Artist>[],
Expand Down
Loading

0 comments on commit 9eee573

Please sign in to comment.