Skip to content

Commit

Permalink
Merge branch 'main' into ms1-readme
Browse files Browse the repository at this point in the history
  • Loading branch information
gruvw authored Apr 11, 2024
2 parents df4ac54 + 6c7eefe commit 787d8d7
Show file tree
Hide file tree
Showing 22 changed files with 580 additions and 224 deletions.
12 changes: 12 additions & 0 deletions lib/utils/ui/not_implemented.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import "package:flutter/material.dart";

class NotImplemented extends StatelessWidget {
const NotImplemented({super.key});

@override
Widget build(BuildContext context) {
return const Center(
child: Text("Feature not yet implemented :("),
);
}
}
22 changes: 0 additions & 22 deletions lib/views/bottom_navigation_bar/navigation_bar_routes.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import "package:flutter/material.dart";
import "package:proxima/models/ui/post_data.dart";
import "package:proxima/views/pages/home/posts/post_card/comment_widget.dart";
import "package:proxima/views/pages/home/posts/post_card/user_bar_widget.dart";
import "package:proxima/views/pages/home/posts/post_card/votes_widget.dart";
import "package:proxima/views/home_content/feed/post_card/comment_widget.dart";
import "package:proxima/views/home_content/feed/post_card/user_bar_widget.dart";
import "package:proxima/views/home_content/feed/post_card/votes_widget.dart";

/// This widget is used to display the post card in the home feed.
/// It contains the post title, description, votes, comments
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/viewmodels/home_view_model.dart";
import "package:proxima/views/pages/home/posts/post_card/post_card.dart";
import "package:proxima/views/home_content/feed/post_card/post_card.dart";
import "package:proxima/views/navigation/routes.dart";
import "package:proxima/views/sort_option_widgets/feed_sort_option/feed_sort_option_chips.dart";

/// This widget is the feed of the home page
/// It contains the posts
class HomeFeed extends HookConsumerWidget {
class PostFeed extends HookConsumerWidget {
static const feedSortOptionKey = Key("feedSortOption");
static const homeFeedKey = Key("homeFeed");
static const emptyHomeFeedKey = Key("emptyHomeFeed");
const HomeFeed({super.key});
static const feedKey = Key("feed");
static const emptyfeedKey = Key("emptyFeed");
static const newPostButtonTextKey = Key("newPostButtonTextKey");
const PostFeed({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final posts = ref.watch(postList);

final emptyHelper = Center(
key: emptyHomeFeedKey,
key: emptyfeedKey,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("No post to display, "),
InkWell(
onTap: () => {
//TODO: Add navigation to create post page
Navigator.pushNamed(context, Routes.newPost.name),
},
child: const Text(
key: newPostButtonTextKey,
"create one",
style: TextStyle(
color: Colors.blue,
Expand All @@ -38,7 +41,7 @@ class HomeFeed extends HookConsumerWidget {
);

final postsCards = ListView(
key: homeFeedKey,
key: feedKey,
children: posts.map((post) => PostCard(post: post)).toList(),
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import "package:flutter/material.dart";
import "package:proxima/utils/ui/not_implemented.dart";
import "package:proxima/views/home_content/feed/post_feed.dart";
import "package:proxima/views/navigation/routes.dart";

/// This enum is used to create the navigation bar routes.
/// It contains the name and icon of the routes.
enum NavigationbarRoutes {
feed("Feed", Icon(Icons.home), null),
challenge("Challenge", Icon(Icons.emoji_events), null),
addPost(
"New post",
CircleAvatar(
child: Icon(Icons.add),
),
Routes.newPost,
),
group("Group", Icon(Icons.group), null),
map("Map", Icon(Icons.place), null);

static const defaultLabelText = "Proxima";

final String name;
final Widget icon;

// Non-null if it requires a push
final Routes? routeDestination;

const NavigationbarRoutes(
this.name,
this.icon,
this.routeDestination,
);

Widget page() {
if (routeDestination != null) {
throw Exception("Route must be pushed.");
}

// TODO implement other routes
switch (this) {
case feed:
return const PostFeed();
case _:
return const NotImplemented();
}
}

String pageLabel() {
switch (this) {
case challenge:
return "Your challenges";
case _:
return defaultLabelText;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/views/bottom_navigation_bar/navigation_bar_routes.dart";
import "package:proxima/views/navigation/bottom_navigation_bar/navigation_bar_routes.dart";

/// This widget is the bottom navigation bar of the home page.
/// It contains the navigation routes to the different pages.
class NavigationBottomBar extends HookConsumerWidget {
static const navigationBottomBarKey = Key("navigationBottomBar");

const NavigationBottomBar({super.key});
final ValueNotifier selectedIndex;

const NavigationBottomBar({
super.key,
required this.selectedIndex,
});

@override
Widget build(BuildContext context, WidgetRef ref) {
Expand All @@ -22,10 +27,17 @@ class NavigationBottomBar extends HookConsumerWidget {
key: navigationBottomBarKey,
height: 90,
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
// TODO set the index of the selected page depending on the page
selectedIndex: 0,
onDestinationSelected: (int index) {
//TODO add the navigation to the pages
selectedIndex: selectedIndex.value,
onDestinationSelected: (int nextIndex) {
final selectedRoute = NavigationbarRoutes.values[nextIndex];

if (nextIndex != selectedIndex.value) {
if (selectedRoute.routeDestination != null) {
Navigator.pushNamed(context, selectedRoute.routeDestination!.name);
} else {
selectedIndex.value = nextIndex;
}
}
},
destinations: destinations,
);
Expand Down
24 changes: 24 additions & 0 deletions lib/views/navigation/leading_back_button/leading_back_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import "package:flutter/material.dart";

class LeadingBackButton extends StatelessWidget {
static const leadingBackButtonKey = Key("leadingBackButtonKey");

final VoidCallback? onPressed;

const LeadingBackButton({
super.key,
this.onPressed,
});

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
key: leadingBackButtonKey,
onPressed: onPressed ?? () => Navigator.pop(context),
icon: const Icon(Icons.arrow_back),
),
);
}
}
28 changes: 14 additions & 14 deletions lib/views/pages/create_account_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/utils/ui/scrollable_if_too_high.dart";
import "package:proxima/viewmodels/login_view_model.dart";
import "package:proxima/views/navigation/leading_back_button/leading_back_button.dart";
import "package:proxima/views/navigation/routes.dart";

class CreateAccountPage extends HookConsumerWidget {
static const logoutButtonKey = Key("logout");
static const confirmButtonKey = Key("confirm");

static const uniqueUsernameFieldKey = Key("uniqueUsername");
Expand All @@ -17,20 +17,20 @@ class CreateAccountPage extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
navigateToLoginPageOnLogout(context, ref);

return Scaffold(
appBar: AppBar(
leading: IconButton(
key: logoutButtonKey,
onPressed: () {
ref.read(loginServiceProvider).signOut();
},
icon: const Icon(Icons.arrow_back),
return PopScope(
canPop: false,
onPopInvoked: (bool didPop) {
ref.read(loginServiceProvider).signOut();
},
child: Scaffold(
appBar: AppBar(
leading: const LeadingBackButton(),
title: const Text("Create your account"),
),
body: const Padding(
padding: EdgeInsets.only(left: 50, right: 50),
child: Center(child: _CreateAccountPageContent()),
),
title: const Text("Create your account"),
),
body: const Padding(
padding: EdgeInsets.only(left: 50, right: 50),
child: Center(child: _CreateAccountPageContent()),
),
);
}
Expand Down
36 changes: 17 additions & 19 deletions lib/views/pages/home/home_page.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
import "package:flutter/material.dart";
import "package:flutter_hooks/flutter_hooks.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/viewmodels/login_view_model.dart";
import "package:proxima/views/bottom_navigation_bar/navigation_bottom_bar.dart";
import "package:proxima/views/navigation/routes.dart";
import "package:proxima/views/pages/home/posts/home_feed.dart";
import "package:proxima/views/pages/home/top_bar/home_top_bar.dart";
import "package:proxima/views/navigation/bottom_navigation_bar/navigation_bar_routes.dart";
import "package:proxima/views/navigation/bottom_navigation_bar/navigation_bottom_bar.dart";
import "package:proxima/views/pages/home/top_bar/app_top_bar.dart";

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

@override
Widget build(BuildContext context, WidgetRef ref) {
ref.listen(isUserLoggedInProvider, (_, isLoggedIn) {
if (!isLoggedIn) {
// Go to login page when the user is logged out
Navigator.pushNamedAndRemoveUntil(
context,
Routes.login.name,
(route) => false,
);
}
});
navigateToLoginPageOnLogout(context, ref);

final currentPageIndex = useState(NavigationbarRoutes.feed.index);

return Scaffold(
appBar: AppBar(
title: const HomeTopBar(),
title: AppTopBar(
labelText:
NavigationbarRoutes.values[currentPageIndex.value].pageLabel(),
),
),
bottomNavigationBar: NavigationBottomBar(
selectedIndex: currentPageIndex,
),
bottomNavigationBar: const NavigationBottomBar(),
body: const Padding(
padding: EdgeInsets.only(left: 8, right: 8),
child: HomeFeed(),
body: Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: NavigationbarRoutes.values[currentPageIndex.value].page(),
),
);
}
Expand Down
59 changes: 59 additions & 0 deletions lib/views/pages/home/top_bar/app_top_bar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/viewmodels/login_view_model.dart";
import "package:proxima/views/navigation/routes.dart";

/// This widget is the top bar of the home page
/// It contains the feed sort option and the user profile picture
class AppTopBar extends HookConsumerWidget {
static const homeTopBarKey = Key("homeTopBar");
static const profilePictureKey = Key("profilePicture");
static const logoutButtonKey = Key("logoutButton");

final String labelText;

const AppTopBar({super.key, required this.labelText});

@override
Widget build(BuildContext context, WidgetRef ref) {
final title = Text(
labelText,
style: Theme.of(context).textTheme.headlineMedium,
);

Widget userAvatar = CircleAvatar(
child: Stack(
children: [
const Center(child: Text("PR")),
Material(
shape: const CircleBorder(),
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
child: InkWell(
key: profilePictureKey,
onTap: () => {
Navigator.pushNamed(context, Routes.profile.name),
},
),
),
],
),
);

return Row(
key: homeTopBarKey,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
title,
// Temporary logout button
IconButton(
key: logoutButtonKey,
onPressed: () => ref.read(loginServiceProvider).signOut(),
icon: const Icon(Icons.logout),
),
userAvatar,
],
);
}
}
Loading

0 comments on commit 787d8d7

Please sign in to comment.