Code With Bisky

Flutter Chat Application with Appwrite | Splash, Intro and Login Pages

In this video, I will show you how to build a chat application using Flutter and Appwrite. Appwrite is a self-hosted backend platform that provides developers with a set of easy-to-use and integrate REST APIs to manage their core backend needs. Flutter is a cross-platform mobile development framework that allows you to build native apps for iOS, Android, and web from a single codebase.

Key Topics covered:

  • Create Splash Screen
  • Create Intro Screen
  • Create Login Screen
  • Add routing between these screens

Description:

The tutorial will walk you through the process of creating Splash, Intro and Login Screens. We shall add auto_route dependency for our navigation

Code Snippet(SplashScreen):


 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text("Chat with Bisky"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              ImagePath.logo,
              width: 200,
            )
          ],
        ),
      ),
    );
  }

            @override
      void initState() {
        super.initState();

        Future <void>.delayed(const Duration(seconds: 3));

        print("Delay is done lets go to the next page");
         AutoRouter.of(context).push(const IntroPage());
      }

    

Add the above code in _MyHomePageState class

Code Snippet (IntroPage.dart):

  • create pages directory
  • lib/pages
  • create introduction directory inside pages
  • lib/pages/introduction

import 'package:auto_route/annotations.dart';
import 'package:auto_route/auto_route.dart';
import 'package:chat_with_bisky/route/app_route/AppRouter.gr.dart';
import 'package:chat_with_bisky/values/values.dart';
import 'package:flutter/material.dart';
import 'package:introduction_screen/introduction_screen.dart';

@RoutePage()
class IntroPage extends StatefulWidget{
  @override
  _IntroPageState  createState() {
    return _IntroPageState();
  }
}


class  _IntroPageState extends State<IntroPage>{
  @override
  Widget build(BuildContext context) {
    return introWidget();
  }
  Widget introWidget(){
    return IntroductionScreen(
      showSkipButton: false,
      next: const Icon(Icons.arrow_forward_ios),
      pages: [
        PageViewModel(
          title: "Chat With Loved Ones",
          body: "Chat with your loved ones and share your experience",
          image: _buildImage(ImagePath.intro1)
        ),
        PageViewModel(
            title: "More Secure",
            body: "We are more concerned about your privacy",
            image: _buildImage(ImagePath.intro2)
        ),
        PageViewModel(
            title: "Share Files",
            body: "Share images, videos, location and documents with your loved ones",
            image: _buildImage(ImagePath.intro3)
        )
      ],
      onDone:onDonePress,
      showDoneButton: true,
      done: const Text('Done', style: TextStyle(fontWeight: FontWeight.w600)),
    );
  }


  Widget _buildImage(String imagePath){
    return Image.asset(imagePath,width: 150,);
  }

  void onDonePress() {
    AutoRouter.of(context).push(const LoginPage());
  }
}

Code Snippet (Login.dart):


import 'package:auto_route/annotations.dart';
import 'package:chat_with_bisky/values/values.dart';
import 'package:flutter/material.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
import 'package:introduction_screen/introduction_screen.dart';

@RoutePage()
class LoginPage extends StatefulWidget{

  @override
  _LoginPageState  createState() {
    return _LoginPageState();
  }

}
class  _LoginPageState extends State<LoginPage>{

  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  final TextEditingController controller = TextEditingController();
  String initialCountry = 'BE';
  PhoneNumber number = PhoneNumber(isoCode: 'BE');
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Stack(
        children: [
          Image.asset(ImagePath.background, height: MediaQuery.of(context).size.height,),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
            InternationalPhoneNumberInput(
              onInputChanged: (PhoneNumber number) {
                print(number.phoneNumber);
              },
              onInputValidated: (bool value) {
                print(value);
              },
              selectorConfig: const SelectorConfig(
                selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
              ),
              ignoreBlank: false,
              autoValidateMode: AutovalidateMode.disabled,
              selectorTextStyle: TextStyle(color: Colors.black),
              initialValue: number,
              textFieldController: controller,
              formatInput: true,
              keyboardType:
              const TextInputType.numberWithOptions(signed: true, decimal: true),
              inputBorder: const OutlineInputBorder(),
              onSaved: (PhoneNumber number) {
                print('On Saved: $number');
              },
            ),
            ElevatedButton(
              onPressed: () {
                formKey.currentState?.validate();
              },
              child: const Text('Verify'),
            ),
          ],)
        ],
      ),
    );
  }
  void getPhoneNumber(String phoneNumber) async {
    PhoneNumber number =
    await PhoneNumber.getRegionInfoFromPhoneNumber(phoneNumber, 'US');
    setState(() {
      this.number = number;
    });
  }
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}
    

Code Snippet (AppRouter.dart):

Add IntroPage.page and LoginPage.page routes below MyHomePage.page,initial: true)


 List<AutoRoute> get routes=>[
    AutoRoute(page: MyHomePage.page,initial: true),
    AutoRoute(page: IntroPage.page),
    AutoRoute(page: LoginPage.page),
  ];
        
        

Code Snippet (images.dart):

Add below images constants in images.dart in lib/values/images.dart


  static const String logo = "$imageDir/logo.png";
  static const String intro1 = "$imageDir/chat_with_loved_ones.jpg";
  static const String intro2 = "$imageDir/security.jpg";
  static const String intro3 = "$imageDir/share_photos.jpg";
        
        

Code Snippet (pubspec.yaml):

Add below assets configs


  assets:
    - assets/images/
    - assets/svg/
        
        

Conclusion:

We managed to create SplashScreen, IntroPage and LoginPages. In the next video, we shall implement Appwrite Phone Authentication. You can customize with your own images by adding them assets folder.