Chat SDK

I created a chat library to help you build chat systems quickly and easily, with ready-to-use tools that save time and effort.

N|Solid

chatsList


ChatsList(
    title: 'chats',
    itemCount: getChats(),
    refreshController: refreshController,
    onRefresh: () async {
        await loadingNewChat(hasNext: true);
    },
    itemBuilder: (BuildContext context, int index) {
        return const ListTile(
            title: Text('Ali Jassib'),
            subtitle: Text('Hello, How are you?'),
            trailing: Icon(Icons.arrow_forward_ios),
        );
    },
),

Parameters

title

  • A string that represents the title or heading of the chat list.
  • Example: 'chats'.

itemCount

  • Defines the total number of chat items to be displayed in the list.
  • This value is dynamically retrieved using the getChats() function.

refreshController

  • Manages the pull-to-refresh functionality.
  • Used with libraries like pull_to_refresh to allow users to refresh the chat list.

onRefresh

  • A callback function triggered when the user performs a pull-to-refresh action.
  • Example: Calls the loadingNewChat(hasNext: true) function to load additional chat data asynchronously.

itemBuilder

  • A function responsible for building each chat item in the list.
  • Parameters:
    • context: The BuildContext of the widget.
    • index: The index of the current chat item.

Chat

Chat(
          title: 'Ali Jassib',
          refreshController: refreshController,
          itemCount: getMessages(),
          onRefresh: () async{
            await loadingNewMessage(hasNext: true);
          },
          scrollController: scrollController,
          inputWidget: inputWidget,
          itemBuilder: (context, index) {
            return messageCard(index);
          },
        ),

Parameters

title

  • A string that represents the title of the chat.
  • Example: 'Ali Jassib'.

refreshController

  • Manages the state of the pull-to-refresh functionality.
  • Used with libraries like pull_to_refresh to allow users to refresh the chat messages.

itemCount

  • Specifies the total number of messages to display.
  • This value is dynamically fetched using the getMessages() function.

onRefresh

  • A callback function triggered when the user performs a pull-to-refresh action.
  • Example: Calls the loadingNewMessage(hasNext: true) function to fetch new messages asynchronously.

scrollController

  • Controls the scrolling behavior of the chat view.
  • Useful for programmatically scrolling to a specific position or managing the user's scroll actions.

inputWidget

  • A widget that handles user input for sending messages.
  • Example: A custom input field or toolbar widget.

itemBuilder

  • A function responsible for rendering each message in the chat view.
  • Parameters:
    • context: The BuildContext for the widget.
    • index: The index of the current message being rendered.

Full Example for chat list widget

We provided you with a set of classes to simplify the task of building your UI efficiently and effortlessly.:

import 'package:chating/chating.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ChatsList(
          title: 'chats',
          itemCount: getChats(),
          refreshController: refreshController,
          onRefresh: () async {
            await loadingNewChat(hasNext: true);
          },
          itemBuilder: (BuildContext context, int index) {
            return const ListTile(
              title: Text('Ali Jassib'),
              subtitle: Text('Hello, How are you?'),
              trailing: Icon(Icons.arrow_forward_ios),
            );
          },
        ),
      ),
    );
  }

  RefreshController get refreshController => RefreshController();

  Future<void> loadingNewChat({required bool hasNext}) async {
    if (hasNext) {
      // write your logic code here
      refreshController.loadComplete();
    } else {
      refreshController.loadNoData();
    }
  }

  // Here, you can later add the model you receive from the backend and set it up in this spot so you can use and inject it into the UI seamlessly.
  int getChats() {
    // write your logic code here
    return 10;
  }
}

MessageCard & ImageCard Widgets

The MessageCard and ImageCard widgets are designed for chat applications to represent individual text or image messages. Both widgets are customizable and can be tailored to fit various chat designs.


MessageCard Widget

The MessageCard widget is used to display a text message in the chat.

Parameters

  • text

    • The message content.
    • Example: 'Hello World!'.
  • date

    • The timestamp of the message.
    • Example: '12:00 PM'.
  • isSender

    • A boolean value indicating whether the message was sent by the user (true) or received from another participant (false).
    • Example: true.
  • sent

    • A boolean value that indicates if the message was successfully sent (true) or is pending (false).
    • Example: true.

Example Usage

const MessageCard(
  text: 'Hello World!',
  date: '12:00 PM',
  isSender: true,
  sent: true,
);

ImageCard Widget

The ImageCard widget is designed to display an image message in a chat interface. It includes properties for customization, such as the image source, message metadata, and sender information.

Parameters

  • id

    • A unique identifier for the image message.
    • Example: '123'.
  • image

    • A widget representing the image content.
    • Typically loaded using constructors like Image.network, Image.asset, etc.
    • Example:
      Image.network('https://via.placeholder.com/150')
      
  • date

    • A string representing the timestamp of the message.
    • Example: '12:00 PM'.
  • isSender

    • A boolean indicating whether the message was sent by the user (true) or received from another participant (false).
    • Example: false.
  • sent

    • A boolean indicating whether the image message was successfully sent (true) or is pending (false).
    • Example: true.

Example Usage

ImageCard(
  id: '123',
  image: Image.network('https://via.placeholder.com/150'),
  date: '12:00 PM',
  isSender: false,
  sent: true,
);

Full Example for chat widget

To start a chat with someone and begin the conversation, the UI will look like this:

import 'dart:math';

import 'package:chating/chating.dart';
import 'package:chating/src/components/custom_typing_card.dart';
import 'package:chating/src/components/image_card.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Chat(
          title: 'Ali Jassib',
          refreshController: refreshController,
          itemCount: getMessages(),
          onRefresh: () async{
            await loadingNewMessage(hasNext: true);
          },
          scrollController: scrollController,
          inputWidget: inputWidget,
          itemBuilder: (context, index) {
            return messageCard(index);
          },
        ),
      ),
    );
  }

  RefreshController get refreshController => RefreshController();
  ScrollController get scrollController => ScrollController();
  TextEditingController get textController => TextEditingController();


  // Here, you can later add the model you receive from the backend and set it up in this spot so you can use and inject it into the UI seamlessly.
  int getMessages() {
    return 10;
  }

  Future<void> loadingNewMessage({bool hasNext = false}) async {
     if (hasNext) {
      // write your logic code here
      refreshController.loadComplete();
    } else {
      refreshController.loadNoData();
    }
  }

  Widget get inputWidget => CustomTypingCard(
        textController: textController,
        scrollController: scrollController,
        onSend: () {
          // Send message logic or call the function to send the message
        },
        onTapImageUpload: () {
          // Image upload logic or call the function to upload the image
        },
        iconSend: const Icon(Icons.send),
        hintText: 'Type a message',
      );
}

Backend Integration

This document provides a detailed guide to integrating backend services for a chat application, including real-time SignalR connections, user authentication, chat management, and message handling.


Postman Documentation https://documenter.getpostman.com/view/25580280/2sAYBYepwg

Constant

All API requests use the following base URL:
BaseUrl: http://95.179.242.182:6014

Get api key and platform id from integretion team X-PLATFORM-ID : X-API-KEY :


Package Required

Add the following package to your pubspec.yaml:

signalr_netcore: last version
retrofit: last version

use retrofit

part 'client.g.dart';

@RestApi(baseUrl: '${baseUrl}')
abstract class RestClient {
  factory RestClient(Dio dio, {String? baseUrl}) = _RestClient;
}

login

@POST('/authentication/user-platform-login')
  Future<AuthModel> login(
    @Header('X-PLATFORM-ID') String platformId,
    @Header('X-API-KEY') String key,
    @Body() LoginRequestModel body
  );

model

class LoginRequestModel {
    final String userId;
    final String name;
    final int phoneNumber;
}

SignalR Integration

you can get TOKEN from login

    SignalR signlR = SignalR(baseUrl: baseUrl, token: token); // initialize 
    signlR.onReceiveMessage(callback: (data){});
    signlR.startConnection(); // if you need to start the connection
    signlR.stopConnection(); // end connection 

Get Chats From API

  @GET('/chats')
  Future<ChatsModel> getChats();

navigate to chat

  @GET('/chats/$chatId/token')
  Future<ChatTokenModel> navigate(
    @Path('chatId') String chatId,
    @Query('senderId') String? senderId,
  );

new chat api

  @POST('/chats')
  Future<ChatTokenModel> newChat(
    @Header('X-PLATFORM-ID') String platformId,
    @Header('X-API-KEY') String key,
    @Body() NewChatModelRequest body
  );
  

model

class NewChatModelRequest {
    final String senderName;
    final int senderPhoneNumber;
    final String senderPlatformUserId;
    final String receiverName;
    final int receiverPhoneNumber;
    final String receiverPlatformUserId
}

get message for this chat

  @GET('/chats/messages')
  Future<MessageModel> getMessage(
    @Query('Page') int page
    @Query('PageSize') int pageSize
  );

send message

  @POST('/messages')
  @Multipart
  Future<Response> sendMessage({
    @Part(name : 'text') required String text,
    @Part(name : 'File') required MultipartFile file,
  });