-
Notifications
You must be signed in to change notification settings - Fork 7
Fahad AlQarni - Task-2T2 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,207 +1,19 @@ | ||
| # Task 2: Introduction to Navigation | ||
| # Fake Social Media App | ||
| My implementation of the second task of the GDSC and Programming Club Flutter tasks. | ||
| As requested, the app has 4 main pages, as well as inner pages to inspect posts and profiles. | ||
|
|
||
| ## Table of Contents | ||
| ### Home Page | ||
|  | ||
|
|
||
| - [Overview](#overview) | ||
| - [Learning Objectives](#learning-objectives) | ||
| - [Setup and Tutorial](#setup-and-tutorial) | ||
| - [Project Overview](#project-overview) | ||
| - [Submission Guidelines](#submission-guidelines) | ||
| ### Profile Page | ||
|  | ||
|
|
||
| ## Overview | ||
| ### Search Page and Functionality | ||
|  | ||
|  | ||
|
|
||
| In this project, you will continue on your previous profile page and create 4 main pages for your new social media app. The pages you select are up to you, but they should be related to a social media app. You can use the navigation method of your choice (Material page route or Named routes). | ||
| ### The Notifications Page | ||
|  | ||
|
|
||
| ## Learning Objectives | ||
|
|
||
| - Learn how to navigate between pages in Flutter. | ||
| - Learn how to create a bottom navigation bar. | ||
| - Learn how to push and pop pages in Flutter. | ||
|
|
||
| ## Resources | ||
|
|
||
| - [Bottom Navigation Bar](https://www.youtube.com/watch?v=xoKqQjSDZ60) | ||
| - [Modern Navigation Bar](https://www.youtube.com/watch?v=FEvYl8Mzsxw) | ||
| - [Flutter Basic Navigation](https://www.youtube.com/watch?v=C6nTXjQFVKI) | ||
|
|
||
| ## Custom Resources | ||
|
|
||
| [Navigation Tutorial (English)](https://www.youtube.com/watch?v=iWwSdygvrsA&list=PL1LV47jH4m0cGRTJFqfN39YpNbLDY9_NE&pp=iAQB) | ||
|
|
||
| ## Setup and Tutorial | ||
|
|
||
| ### 1. Setup | ||
|
|
||
| #### 1.1. Git and Github | ||
|
|
||
| To setup this project, please follow this simple git and github tutorial provided [here](https://github.com/GDSC-IAU/git-and-github) | ||
|
|
||
| ### Tutorial | ||
|
|
||
| #### 2.1. Setting up a Bottom Navigation Bar | ||
|
|
||
| ```dart | ||
| import 'package:flutter/material.dart'; | ||
| // Import all of the pages that we want to navigate to | ||
| // ............... | ||
|
|
||
| // Create a stateful widget | ||
| class MainScreen extends StatefulWidget { | ||
| const MainScreen({super.key}); | ||
| @override | ||
| _MainScreenState createState() => _MainScreenState(); | ||
| } | ||
|
|
||
| // Create a state | ||
| class _MainScreenState extends State<MainScreen> { | ||
| // Create a list of pages that we want to navigate to | ||
| final List<Widget> _pages = [ | ||
| // Add all of the pages that we want to navigate to | ||
| // ............... | ||
| ]; | ||
|
|
||
| // Create a variable to keep track of the current page | ||
| int _selectedPageIndex = 0; | ||
|
|
||
| // Create a method to change the current page | ||
| void _selectPage(int index) { | ||
| setState(() { | ||
| _selectedPageIndex = index; | ||
| }); | ||
| } | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| // Create a scaffold | ||
| return Scaffold( | ||
| // Create a bottom navigation bar | ||
| bottomNavigationBar: BottomNavigationBar( | ||
| // Set the current page | ||
| currentIndex: _selectedPageIndex, | ||
| // Set the items in the bottom navigation bar | ||
| items: [ | ||
| // Create a bottom navigation bar item | ||
| BottomNavigationBarItem( | ||
| // Set the icon of the item | ||
| icon: Icon(Icons.home), | ||
| // Set the label of the item | ||
| label: 'Home', | ||
| ), | ||
| // Create a bottom navigation bar item | ||
| BottomNavigationBarItem( | ||
| // Set the icon of the item | ||
| icon: Icon(Icons.search), | ||
| // Set the label of the item | ||
| label: 'Search', | ||
| ), | ||
| // Create a bottom navigation bar item | ||
| BottomNavigationBarItem( | ||
| // Set the icon of the item | ||
| icon: Icon(Icons.shopping_cart), | ||
| // Set the label of the item | ||
| label: 'Cart', | ||
| ), | ||
| // Create a bottom navigation bar item | ||
| BottomNavigationBarItem( | ||
| // Set the icon of the item | ||
| icon: Icon(Icons.person), | ||
| // Set the label of the item | ||
| label: 'Profile', | ||
| ), | ||
| ], | ||
| // Set the action that happens when an item is pressed | ||
| onTap: _selectPage, | ||
| ), | ||
| // Set the body of the scaffold | ||
| body: _pages[_selectedPageIndex], | ||
| ); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| #### 2.2. Navigating to a New Page | ||
|
|
||
| ##### 2.2.1 Using Material page Route | ||
|
|
||
| ```dart | ||
| import 'package:flutter/material.dart'; | ||
| // Import the page that we want to navigate to | ||
| // ............... | ||
|
|
||
| // Navigate Function using Push | ||
| void _navigate(BuildContext context) { | ||
| Navigator.push( | ||
| context, | ||
| MaterialPageRoute( | ||
| builder: (context) => SomePage(args: args,)// Add the page that we want to navigate to | ||
| ), | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| ##### 2.2.2 Using Named Routes | ||
|
|
||
| ```dart | ||
| import 'package:flutter/material.dart'; | ||
| // Import all of the pages that we want to navigate to | ||
| // ............... | ||
|
|
||
| // In your MaterialApp widget, add the routes parameter | ||
| MaterialApp( | ||
| // Add the routes parameter | ||
| routes: { | ||
| // Add all of the pages that we want to navigate to | ||
| // ............... | ||
| "/somePage": (context) => SomePage(args: args),// Add the page that we want to navigate to | ||
| "/someOtherPage": (context) => SomeOtherPage(args: args),// Add the page that we want to navigate to | ||
| }, | ||
| ); | ||
| ``` | ||
|
|
||
| Now we can use these named routes to navigate to a new page. | ||
|
|
||
| ```dart | ||
| // Navigate Function using Named Routes | ||
| void _navigate(BuildContext context) { | ||
| Navigator.pushNamed( | ||
| context, | ||
| '/somePage',// Add the name of the page that we want to navigate to | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| ## Project Overview | ||
|
|
||
| In this project, you will continue on your previous profile page and create 4 main pages for your new social media app. The pages you select are up to you, but they should be related to a social media app. You can use the navigation method of your choice (Material page route or Named routes). | ||
|
|
||
| ### Requirements | ||
|
|
||
| - The app must have a bottom navigation bar. | ||
| - The app must have a home page, search page, notifications page, and profile page. | ||
| - The app must have some inner page that uses the navigation method of your choice. (Material page route or Named routes) | ||
| - The app structure should be clean and easy to understand. | ||
| - The app should be well documented. | ||
| - The readme file should contain a brief description of the project and a screenshot of the app. | ||
|
|
||
| ### Bonus | ||
|
|
||
| - Use a package from pub.dev to create a stylized bottom navigation bar | ||
| - Use a Hero widget to create a transition between pages | ||
|
|
||
| ## Submission Guidelines | ||
|
|
||
| - The app should be pushed to Github and a pull request should be created. You can check how to push your code to Github in section [2.1.2 Add Changes](https://github.com/Programming-Club-IAU/git-and-github#212-add-changes). | ||
| - The pull request title should be in the following format: `<your-name> - <project-name>`. You can check how to make a pull request in section [2.1.5. Create a pull request](ttps://github.com/Programming-Club-IAU/git-and-github#215-create-a-pull-request). | ||
| - The pull request description should contain the following: | ||
| - A brief description of the project. | ||
| - A screenshot of the app. | ||
|
|
||
| ## Design Inspiration | ||
|
|
||
| ### [Design 1](https://dribbble.com/shots/23642089-AI-Driven-Platform-for-Accelerating-Civic-Solutions) | ||
|
|
||
|  | ||
|
|
||
| ### [Design 2](https://dribbble.com/shots/17948799-Social-Media-App) | ||
|
|
||
|  | ||
| ### Models | ||
| The app uses 2 main models, the user model, and the post model. The "users.dart" and "posts.dart" files are essentially like big storage files to declare models so that it can make the process of adjusting the app much easier. It contains frequently used user models and post models respectively. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import 'package:flutter/material.dart'; | ||
|
|
||
| class DefaultColors { | ||
| static const Color profileCardColor = Color.fromARGB(255, 76, 73, 86); | ||
|
|
||
| static const Color fieldColor = Color.fromARGB(255, 47, 45, 56); | ||
| static const Color fieldOutlineColor = Color.fromARGB(255, 75, 74, 83); | ||
|
|
||
| static const Color blockColor = Color.fromARGB(255, 39, 35, 43); | ||
|
|
||
| // This is done for convenience's sake, I find that matching the blocks outline with the field color gives a nice look | ||
| // so this is just a way for me to avoid having to reset both the block outline and the field color each time I change it | ||
| static const Color blockOutlineColor = fieldColor; | ||
|
|
||
| static const Color userHandleColor = Color.fromARGB(255, 156, 156, 156); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import 'package:flutter/material.dart'; | ||
| import 'user_model.dart'; | ||
|
|
||
| class PostModel { | ||
| const PostModel( | ||
| this.text, { | ||
| required this.user, | ||
| this.imageAttachment, | ||
| this.parent, | ||
| this.replies, | ||
| this.likes = 0, | ||
| this.dislikes = 0, | ||
| this.favorites = 0, | ||
| }); | ||
|
|
||
| final UserModel user; | ||
| final String text; | ||
| final ImageProvider? imageAttachment; | ||
| final PostModel? parent; | ||
| final List<PostModel>? replies; | ||
| final int likes; | ||
| final int dislikes; | ||
| final int favorites; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import 'package:flutter/material.dart'; | ||
|
|
||
| class UserModel { | ||
| const UserModel({ | ||
| required this.handle, | ||
| required this.name, | ||
| this.profilePic = const AssetImage("assets/profile_pics/default.jpg"), | ||
| this.profileBio, | ||
| this.profileBanner, | ||
| this.following = 0, | ||
| this.followers = 0, | ||
| }); | ||
|
|
||
| final String handle; | ||
| final String name; | ||
| final ImageProvider profilePic; | ||
| final String? profileBio; | ||
| final ImageProvider? profileBanner; | ||
| final int following; | ||
| final int followers; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import 'package:flutter/material.dart'; | ||
|
|
||
| import 'users.dart'; | ||
| import 'models/post_model.dart'; | ||
|
|
||
| class FahadPosts { | ||
| static const PostModel persona = PostModel( | ||
| "The new Persona 3 remake is AWESOME", | ||
| user: Users.fahad, | ||
| likes: 6, | ||
| favorites: 2, | ||
| dislikes: 1, | ||
| imageAttachment: AssetImage("assets/posts/persona.jpg"), | ||
| ); | ||
| static const PostModel flutter = PostModel( | ||
| "Learning flutter's been pretty cool", | ||
| user: Users.fahad, | ||
| likes: 2, | ||
| ); | ||
| } | ||
|
Comment on lines
+6
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea to separate the posts, but I recommend you create a field in Read about encapsulation
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So just a little commentary on this. I remember now that I had initially thought of this when I was writing the code, but I thought that it would be an unnecessary performance (specifically memory) overhead to associate each In retrospect, this issue would only really be an issue if it isn't the case that the So your approach is probably right, but I just seemed to have overthought the performance implications of having a List variable inside a class in Dart, and overlooked how dynamic arrays work for most languages :) If you're interested more in this topic, here are some great resources for learning about it:
And of course, thank you Hassan and Arwa for your leadership of the GDSC dev unit :) |
||
|
|
||
| class RadwanPosts { | ||
| static const PostModel event = PostModel( | ||
| "Yesterday's event was probably the best CCSIT event of all time ngl", | ||
| user: Users.radwan, | ||
| likes: 8, | ||
| favorites: 3, | ||
| ); | ||
| static const PostModel workshop = PostModel( | ||
| "Everybody don't forget to register for tomorrow's workshop!", | ||
| user: Users.radwan, | ||
| likes: 3, | ||
| ); | ||
| } | ||
|
|
||
| class HassanPosts { | ||
| static const PostModel github = PostModel( | ||
| "Thank you everyone who attended our github workshop!", | ||
| user: Users.hassan, | ||
| likes: 7, | ||
| ); | ||
| static const PostModel math = PostModel( | ||
| "Mathematics is the art of explanation", | ||
| user: Users.hassan, | ||
| likes: 3, | ||
| ); | ||
| } | ||
|
|
||
| class Posts { | ||
| static const List<PostModel> allPosts = [ | ||
| FahadPosts.flutter, | ||
| FahadPosts.persona, | ||
| RadwanPosts.event, | ||
| RadwanPosts.workshop, | ||
| HassanPosts.github, | ||
| HassanPosts.math, | ||
| ]; | ||
|
|
||
| static const List<PostModel> homeFeed = [ | ||
| FahadPosts.persona, | ||
| RadwanPosts.event, | ||
| HassanPosts.github, | ||
| HassanPosts.math, | ||
| FahadPosts.flutter, | ||
| RadwanPosts.workshop, | ||
| ]; | ||
|
|
||
| static List<PostModel> searchPosts(String searchCriteria) { | ||
| List<PostModel> posts = []; | ||
|
|
||
| for (int i = 0; i < allPosts.length; i++) { | ||
| if (allPosts[i] | ||
| .text | ||
| .toLowerCase() | ||
| .contains(searchCriteria.toLowerCase())) { | ||
| posts.add(allPosts[i]); | ||
| } | ||
| } | ||
|
|
||
| return posts; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice idea to gather colors in one place.