clean architecture 4

Instagram Clone Clean Architecture – Part 4

Table of Contents

In the last article we’ve designed main screen of our instagram application which includes the pages like Home, Search, Post, Activity, and Profile we’ve designed all of them also and now it’s time to go forward and design the pages we’ve left in the previous article that pages required navigation.

In your profile page you’ll found the menu icon at the AppBar() look at the code below :

				
					AppBar(
  backgroundColor: backGroundColor,
  title: Text("Username", style: TextStyle(color: primaryColor),),
  actions: [
    Padding(
      padding: const EdgeInsets.only(right: 10.0),
      child: InkWell(
      onTap: () {
        _openBottomModalSheet(context);
      },child: Icon(Icons.menu, color: primaryColor,)),
    )
  ],
)
				
			

We simply wrap it with InkWell() and in the onTap we’ve called our method which is _openBottomModalSheet(context) accepting a parameter context.

Now implement this method below in your build() method.

Code will be :

				
					_openBottomModalSheet(BuildContext context) {
  return showModalBottomSheet(context: context, builder: (context) {
    return Container(
      height: 150,
      decoration: BoxDecoration(color: backGroundColor.withOpacity(.8)),
      child: SingleChildScrollView(
        child: Container(
          margin: EdgeInsets.symmetric(vertical: 10),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 10.0),
                child: Text(
                  "More Options",
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: primaryColor),
                ),
              ),
              SizedBox(
                height: 8,
              ),
              Divider(
                thickness: 1,
                color: secondaryColor,
              ),
              SizedBox(
                height: 8,
              ),
              Padding(
                padding: const EdgeInsets.only(left: 10.0),
                child: GestureDetector(
                  onTap: () {

Navigator.push(context, MaterialPageRoute(builder: (context) => EditProfilePage()));

                  },
                  child: Text(
                    "Edit Profile",
                    style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16, color: primaryColor),
                  ),
                ),
              ),
              sizeVer(7),
              Divider(
                thickness: 1,
                color: secondaryColor,
              ),
              sizeVer(7),
              Padding(
                padding: const EdgeInsets.only(left: 10.0),
                child: Text(
                  "Logout",
                  style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16, color: primaryColor),
                ),
              ),
              sizeVer(7),
            ],
          ),
        ),
      ),
    );
  });
}
				
			

In this if you notice in the code above on the Text(“Edit Profile”) widget we do Navigator.push() to navigate the user to the EditProfilePage().

Create edit_profile_page.dart in the profile directory.

edit_profile_page.dart

				
					import 'package:flutter/material.dart';
import 'package:instagram_clone_app/consts.dart';
import 'package:instagram_clone_app/features/presentation/page/profile/widgets/profile_form_widget.dart';

class EditProfilePage extends StatelessWidget {
  const EditProfilePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backGroundColor,
      appBar: AppBar(
        backgroundColor: backGroundColor,
        title: Text("Edit Profile"),
        leading: GestureDetector(
            onTap: () => Navigator.pop(context),
            child: Icon(
              Icons.close,
              size: 32,
            )),
        actions: [
          Padding(
            padding: const EdgeInsets.only(right: 10.0),
            child: Icon(
              Icons.done,
              color: blueColor,
              size: 32,
            ),
          )
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10),
        child: SingleChildScrollView(
          child: Column(
            children: [
              Center(
                child: Container(
                  width: 120,
                  height: 120,
                  decoration: BoxDecoration(
                    color: secondaryColor,
                    borderRadius: BorderRadius.circular(60),
                  ),
                ),
              ),
              sizeVer(15),
              Center(
                child: Text(
                  "Change profile photo",
                  style: TextStyle(color: blueColor, fontSize: 20, fontWeight: FontWeight.w400),
                ),
              ),
              sizeVer(15),
              ProfileFormWidget(title: "Name"),
              sizeVer(15),
              ProfileFormWidget(title: "Username"),
              sizeVer(15),
              ProfileFormWidget(title: "Website"),
              sizeVer(15),
              ProfileFormWidget(title: "Bio"),
            ],
          ),
        ),
      ),
    );
  }
}
				
			

then create a widgets directory in the profile directory and inside create a dart file and name it profile_form_widget.

				
					import 'package:flutter/material.dart';
import '../../../../../consts.dart';

class ProfileFormWidget extends StatelessWidget {
  final TextEditingController? controller;
  final String? title;
  const ProfileFormWidget({Key? key, this.title, this.controller}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text("$title", style: TextStyle(color: primaryColor, fontSize: 16),),
        sizeVer(10),
        TextFormField(
          controller: controller,
          style: TextStyle(color: primaryColor),
          decoration: InputDecoration(
              border: InputBorder.none,
              labelStyle: TextStyle(color: primaryColor)
          ),
        ),
        Container(
          width: double.infinity,
          height: 1,
          color: secondaryColor,
        )
      ],
    );
  }
}
				
			

We’re done with our edit profile page.

Now let’s go for comment page. Go to presentation > pages > home > home_page.dart search for the code below.

				
					Icon(Feather.message_circle, color: primaryColor,)
				
			

Wrap this icon with the widget InkWell() or GestureDectactor() both are providing onTap method, open the onTap body and do :

				
					Navigator.push(context, MaterialPageRoute(builder: (context) => CommentPage()));
				
			

But the CommentPage() will throw compile time error for now, So let’s create the comment page also.

Go to > presentation > pages > post > and create a directory comment inside this create a file comment_page.dart.

comment_page.dart.

				
					import 'package:flutter/material.dart';
import 'package:instagram_clone_app/consts.dart';

import '../../../widgets/form_container_widget.dart';

class CommentPage extends StatefulWidget {
  const CommentPage({Key? key}) : super(key: key);

  @override
  State<CommentPage> createState() => _CommentPageState();
}

class _CommentPageState extends State<CommentPage> {

  bool _isUserReplaying = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backGroundColor,
      appBar: AppBar(
        backgroundColor: backGroundColor,
        title: Text("Comments"),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    Container(
                      width: 40,
                      height: 40,
                      decoration: BoxDecoration(
                          color: secondaryColor,
                          shape: BoxShape.circle
                      ),
                    ),
                    sizeHor(10),
                    Text("Username", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: primaryColor),),

                  ],
                ),
                sizeVer(10),
                Text("This is very beautiful place", style: TextStyle(color: primaryColor),),
              ],
            ),
          ),
          sizeVer(10),
          Divider(
            color: secondaryColor,
          ),
          sizeVer(10),
          Expanded(
            child: Container(
              margin: EdgeInsets.symmetric(horizontal: 10),
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    width: 40,
                    height: 40,
                    decoration: BoxDecoration(
                        color: secondaryColor,
                        shape: BoxShape.circle
                    ),
                  ),
                  sizeHor(10),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text("Username", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: primaryColor),),
                              Icon(Icons.favorite_outline, size: 20, color: darkGreyColor,)
                            ],
                          ),
                          sizeVer(4),
                          Text("This is comment", style: TextStyle(color: primaryColor),),
                          sizeVer(4),
                          Row(
                            children: [
                              Text("08/07/2022", style: TextStyle(color: darkGreyColor, fontSize: 12),),
                              sizeHor(15),
                              GestureDetector(onTap: () {
                                setState(() {
                                  _isUserReplaying = !_isUserReplaying;
                                });
                              },child: Text("Replay", style: TextStyle(color: darkGreyColor, fontSize: 12),)),
                              sizeHor(15),
                              Text("View Replays", style: TextStyle(color: darkGreyColor, fontSize: 12),),

                            ],
                          ),
                          _isUserReplaying == true? sizeVer(10) : sizeVer(0),
                          _isUserReplaying == true? Column(
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: [
                              FormContainerWidget(hintText: "Post your replay..."),
                              sizeVer(10),
                              Text(
                                "Post",
                                style: TextStyle(color: blueColor),
                              )
                            ],
                          ) : Container(width: 0, height: 0,)
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          _commentSection()
        ],
      ),
    );
  }

  _commentSection() {
    return Container(
      width: double.infinity,
      height: 55,
      color: Colors.grey[800],
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 10.0),
        child: Row(
          children: [
            Container(
              width: 40,
              height: 40,
              decoration: BoxDecoration(
                  color: secondaryColor,
                  borderRadius: BorderRadius.circular(20)
              ),
            ),
            sizeHor(10),
            Expanded(
                child: TextFormField(
                  style: TextStyle(color: primaryColor),
                  decoration: InputDecoration(
                      border: InputBorder.none,
                      hintText: "Post your comment...",
                      hintStyle: TextStyle(color: secondaryColor)
                  ),
                )),
            Text("Post", style: TextStyle(fontSize: 15, color: blueColor),)
          ],
        ),
      ),
    );
  }
}
				
			

we’re done with the comment page also.

Let’s go for Update Post Page.

Again Go to > presentation > pages > home > home_page.dart and search for the below code.

				
					Icon(Icons.more_vert, color: primaryColor,)
				
			

This is the first row of our single post the place from where we will control our post like delete or update.

Wrap this with GestureDectator() and go for onTap method and call again the _openBottomModalSheet(context) here and the code for the home bottomModalSheet will be something like this below:

				
					_openBottomModalSheet(BuildContext context) {
  return showModalBottomSheet(context: context, builder: (context) {
    return Container(
      height: 150,
      decoration: BoxDecoration(color: backGroundColor.withOpacity(.8)),
      child: SingleChildScrollView(
        child: Container(
          margin: EdgeInsets.symmetric(vertical: 10),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 10.0),
                child: Text(
                  "More Options",
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: primaryColor),
                ),
              ),
              SizedBox(
                height: 8,
              ),
              Divider(
                thickness: 1,
                color: secondaryColor,
              ),
              SizedBox(
                height: 8,
              ),
              Padding(
                padding: const EdgeInsets.only(left: 10.0),
                child: Text(
                  "Delete Post",
                  style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16, color: primaryColor),
                ),
              ),
              sizeVer(7),
              Divider(
                thickness: 1,
                color: secondaryColor,
              ),
              sizeVer(7),
              Padding(
                padding: const EdgeInsets.only(left: 10.0),
                child: GestureDetector(
                  onTap: () {

Navigator.push(context, MaterialPageRoute(builder: (context) => UpdatePostPage()));


                  },
                  child: Text(
                    "Update Post",
                    style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16, color: primaryColor),
                  ),
                ),
              ),
              sizeVer(7),
            ],
          ),
        ),
      ),
    );
  });
}
				
			

Here again you’ll see Text(“Update Post” ) widget here we call the Navigator.push() in the onTap of GestureDectator(). This will navigate us to the UpdatePostPage() which is not created for now so let’s create it also go for it.

Go to > presentation > pages > post > and create update_post_page

update_post_page.dart

				
					import 'package:flutter/material.dart';
import 'package:instagram_clone_app/consts.dart';
import 'package:instagram_clone_app/features/presentation/page/profile/widgets/profile_form_widget.dart';

class UpdatePostPage extends StatelessWidget {
  const UpdatePostPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backGroundColor,
      appBar: AppBar(
        backgroundColor: backGroundColor,
        title: Text("Edit Post"),
        actions: [
          Padding(
            padding: const EdgeInsets.only(right: 10.0),
            child: Icon(Icons.done, color: blueColor, size: 28,),
          )
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10),
        child: SingleChildScrollView(
          child: Column(
            children: [
              Container(
                width: 100,
                height: 100,
                decoration: BoxDecoration(
                  color: secondaryColor,
                  shape: BoxShape.circle
                ),
              ),
              sizeVer(10),
              Text("Username", style: TextStyle(color: primaryColor, fontSize: 16, fontWeight: FontWeight.bold),),
              sizeVer(10),
              Container(
                width: double.infinity,
                height: 200,
                decoration: BoxDecoration(
                  color: secondaryColor
                ),
              ),
              sizeVer(10),
              ProfileFormWidget(
                title: "Description",
              )
            ],
          ),
        ),
      ),
    );
  }
}
				
			

Conclusion

In this part we’ve covered the UI of our Instagram application and in the next article we’ll go for Routing. In order to not miss the upcoming video and article be sure to subscribe to eTechViral and hit the bell icon to make sure you get notified whenever new video is uploaded.

Website:
Have any Questions? Find me on
Share on facebook
Share
Share on twitter
Tweet
Share on linkedin
Share
Share on whatsapp
Share
Share on email
Send

Leave a Reply