Skip to content

Commit

Permalink
feat: add user profile page
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Apr 13, 2024
1 parent f82253c commit 39e97ee
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 108 deletions.
35 changes: 21 additions & 14 deletions lib/collections/routes.dart
Expand Up @@ -18,6 +18,7 @@ import 'package:spotube/pages/library/playlist_generate/playlist_generate_result
import 'package:spotube/pages/lyrics/mini_lyrics.dart';
import 'package:spotube/pages/playlist/liked_playlist.dart';
import 'package:spotube/pages/playlist/playlist.dart';
import 'package:spotube/pages/profile/profile.dart';
import 'package:spotube/pages/search/search.dart';
import 'package:spotube/pages/settings/blacklist.dart';
import 'package:spotube/pages/settings/about.dart';
Expand Down Expand Up @@ -175,20 +176,26 @@ final routerProvider = Provider((ref) {
},
),
GoRoute(
path: "/connect",
pageBuilder: (context, state) => const SpotubePage(
child: ConnectPage(),
),
routes: [
GoRoute(
path: "control",
pageBuilder: (context, state) {
return const SpotubePage(
child: ConnectControlPage(),
);
},
)
])
path: "/connect",
pageBuilder: (context, state) => const SpotubePage(
child: ConnectPage(),
),
routes: [
GoRoute(
path: "control",
pageBuilder: (context, state) {
return const SpotubePage(
child: ConnectControlPage(),
);
},
)
],
),
GoRoute(
path: "/profile",
pageBuilder: (context, state) =>
const SpotubePage(child: ProfilePage()),
)
],
),
GoRoute(
Expand Down
49 changes: 28 additions & 21 deletions lib/components/root/sidebar.dart
Expand Up @@ -23,6 +23,7 @@ import 'package:spotube/provider/spotify/spotify.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
import 'package:spotube/provider/user_preferences/user_preferences_state.dart';
import 'package:spotube/utils/platform.dart';
import 'package:spotube/utils/service_utils.dart';

class Sidebar extends HookConsumerWidget {
final int? selectedIndex;
Expand Down Expand Up @@ -275,29 +276,35 @@ class SidebarFooter extends HookConsumerWidget {
const CircularProgressIndicator()
else if (data != null)
Flexible(
child: Row(
children: [
CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(avatarImg),
onBackgroundImageError: (exception, stackTrace) =>
Assets.userPlaceholder.image(
height: 16,
width: 16,
child: InkWell(
onTap: () {
ServiceUtils.push(context, "/profile");
},
borderRadius: BorderRadius.circular(30),
child: Row(
children: [
CircleAvatar(
backgroundImage:
UniversalImage.imageProvider(avatarImg),
onBackgroundImageError: (exception, stackTrace) =>
Assets.userPlaceholder.image(
height: 16,
width: 16,
),
),
),
const SizedBox(width: 10),
Flexible(
child: Text(
data.displayName ?? context.l10n.guest,
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
style: theme.textTheme.bodyMedium
?.copyWith(fontWeight: FontWeight.bold),
const SizedBox(width: 10),
Flexible(
child: Text(
data.displayName ?? context.l10n.guest,
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
style: theme.textTheme.bodyMedium
?.copyWith(fontWeight: FontWeight.bold),
),
),
),
],
],
),
),
),
IconButton(
Expand Down
29 changes: 24 additions & 5 deletions lib/pages/home/home.dart
Expand Up @@ -3,16 +3,19 @@ import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/connect/connect_device.dart';
import 'package:spotube/components/home/sections/featured.dart';
import 'package:spotube/components/home/sections/friends.dart';
import 'package:spotube/components/home/sections/genres.dart';
import 'package:spotube/components/home/sections/made_for_user.dart';
import 'package:spotube/components/home/sections/new_releases.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/components/shared/page_window_title_bar.dart';
import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/image.dart';
import 'package:spotube/provider/spotify/spotify.dart';
import 'package:spotube/utils/platform.dart';
import 'package:spotube/utils/service_utils.dart';

class HomePage extends HookConsumerWidget {
const HomePage({super.key});
Expand All @@ -34,10 +37,26 @@ class HomePage extends HookConsumerWidget {
actions: [
const ConnectDeviceButton(),
const Gap(10),
IconButton.filledTonal(
icon: const Icon(SpotubeIcons.user),
onPressed: () {},
),
Consumer(builder: (context, ref, _) {
final me = ref.watch(meProvider);
final meData = me.asData?.value;

return IconButton(
icon: CircleAvatar(
backgroundImage: UniversalImage.imageProvider(
(meData?.images).asUrlString(
placeholder: ImagePlaceholder.artist,
),
),
),
style: IconButton.styleFrom(
padding: EdgeInsets.zero,
),
onPressed: () {
ServiceUtils.push(context, "/profile");
},
);
}),
const Gap(10),
],
)
Expand Down
144 changes: 144 additions & 0 deletions lib/pages/profile/profile.dart
@@ -0,0 +1,144 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:skeletonizer/skeletonizer.dart';
import 'package:sliver_tools/sliver_tools.dart';
import 'package:spotube/collections/fake.dart';
import 'package:spotube/collections/spotify_markets.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/components/shared/page_window_title_bar.dart';
import 'package:spotube/extensions/image.dart';
import 'package:spotube/provider/spotify/spotify.dart';
import 'package:url_launcher/url_launcher_string.dart';

class ProfilePage extends HookConsumerWidget {
const ProfilePage({super.key});

@override
Widget build(BuildContext context, ref) {
final ThemeData(:textTheme) = Theme.of(context);

final me = ref.watch(meProvider);
final meData = me.asData?.value ?? FakeData.user;

final userProperties = useMemoized(
() => {
"Email": meData.email ?? "N/A",
"Followers": meData.followers?.total.toString() ?? "N/A",
"Birthday": meData.birthdate ?? "Not born",
"Country": spotifyMarkets
.firstWhere((market) => market.$1 == meData.country)
.$2,
"Subscription": meData.product ?? "Hacker",
},
[meData],
);

return SafeArea(
child: Scaffold(
appBar: const PageWindowTitleBar(
title: Text("Profile"),
titleSpacing: 0,
automaticallyImplyLeading: true,
centerTitle: false,
),
body: Skeletonizer(
enabled: me.isLoading,
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(600),
child: UniversalImage(
path: meData.images.asUrlString(
index: 1,
placeholder: ImagePlaceholder.artist,
),
width: 300,
height: 300,
fit: BoxFit.cover,
),
),
],
),
),
const SliverGap(10),
SliverToBoxAdapter(
child: Text(
meData.displayName ?? "No Name",
style: textTheme.titleLarge,
textAlign: TextAlign.center,
),
),
const SliverGap(20),
SliverCrossAxisConstrained(
maxCrossAxisExtent: 500,
child: SliverToBoxAdapter(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton.icon(
label: const Text("Edit"),
icon: const Icon(SpotubeIcons.edit),
onPressed: () {
launchUrlString(
"https://www.spotify.com/account/profile/",
mode: LaunchMode.externalApplication,
);
},
),
],
),
),
),
SliverCrossAxisConstrained(
maxCrossAxisExtent: 500,
child: SliverToBoxAdapter(
child: Card(
margin: const EdgeInsets.all(10),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Table(
columnWidths: const {
0: FixedColumnWidth(110),
},
children: [
for (final MapEntry(:key, :value)
in userProperties.entries)
TableRow(
children: [
TableCell(
child: Padding(
padding: const EdgeInsets.all(6),
child: Text(
key,
style: textTheme.titleSmall,
),
),
),
TableCell(
child: Padding(
padding: const EdgeInsets.all(6),
child: Text(value),
),
),
],
)
],
),
),
),
),
),
],
),
),
),
);
}
}

0 comments on commit 39e97ee

Please sign in to comment.