Code With Bisky

Build an Interactive Chat App: Flutter User Typing Status Tutorial | Real-time Messaging Tutorial [23]

Key Topics covered:

  • Listening for user typing events
  • Displaying typing indicators in real-time
  • Managing user typing status efficiently

Description:

In this tutorial, you will learn how to create a dynamic user typing status indicator in your Flutter messaging app! In this step-by-step tutorial, you'll discover the secrets to implementing real-time user typing.

Code Snippet(MessageViewModel.dart):

  • lib/pages/dashboard/chat/MessageViewModel.dart

Add code to listen that someone is typing


import 'dart:async';
import 'package:async/async.dart';

            // declare
RestartableTimer? _timer;
StreamSubscription? typingSubscription;


 // add below methods
Future<void> listenFriendIsTyping()async {

    final typingRef = database.ref().child('typing').child(state.friendUserId).child(state.myUserId);
    typingRef.onValue.listen((event) {

      if(event.snapshot.exists){
        state = state.copyWith(onlineStatus: 'typing....');
      }else{
        getUserPresenceStatus(state.friendUserId);
      }

    });
  }

  Future<void> typingChanges(String text)async {

    if(_timer == null){
      fd.DatabaseReference con;
      final typingRef = ownUserTypingRef();
      await database.goOnline();
      con = typingRef.push();
      con.set(true);
      resetOrStartTimer();
    }

  }
  fd.DatabaseReference ownUserTypingRef() {
    return database.ref().child('typing').child(state.myUserId).child(state.friendUserId);
  }
  void resetOrStartTimer() {

    if(_timer == null){
      initializeTimer();
    }else{
      _timer?.reset();
    }
  }

  void initializeTimer() {
   _timer ??= RestartableTimer(const Duration(seconds: 5),  onTimerRunsOut);
  }

  onTimerRunsOut() {

    _timer = null;
    deleteTypingRef();

  }

  void deleteTypingRef() {

    final typingRef = ownUserTypingRef();
    typingRef.remove();
  }

  typingConnectionListener() async{

    final typingRef = ownUserTypingRef();
    await database.goOnline();
    typingSubscription = database.ref().child('.info/connected').onValue.listen((event) {
      if(event.snapshot.value != null){
        typingRef.onDisconnect().remove();
      }
    });
  }


  void disconnect(){

    if(typingSubscription != null){
      typingSubscription?.cancel();
    }
    database.goOffline();
    onTimerRunsOut();
  }

// in initializeMessages() method add below code
state = state.copyWith(friendUserId: receiverUserId,
    myUserId: senderUserId);
 

Code Snippet(MessageScreen.dart):

  • lib/pages/dashboard/chat/MessageScreen.dart

Add typing event


// add below code to the TextFormField
onChanged: (value) {
    messageNotifier?.typingChanges(value);
},


 @override
  void dispose() {

    messageNotifier?.disconnect();
    super.dispose();
  }
// add this code in initState() method
messageNotifier?.listenFriendIsTyping();
 

Conclusion:

We managed to implement user typing status in Real-time. Don't forget to share and join ourDiscord Channel. May you please subscribe to our YouTube Channel.