Locality Social Cloud Chat

locality_social_cloud_chat is a Flutter library that provides a real-time messaging system for managing direct messages and group chats. It supports message delivery, reactions, notifications, and invitations, integrating with the locality_social_cloud API.

Features

  • End-to-End-Encryption: Uses ECDH with elliptic Curve M-511 and ChaCha20 for encryption.
  • Message Reactions: Users can react to messages with predefined or custom reactions.
  • Event-driven Architecture: Respond to specific message types (e.g., text, media) using a PubSub model.
  • Group Chats: Invite users to group chats and manage acceptances.
  • Efficient UI Updates: Implemented using ThrottledChangeNotifier for optimized state updates.
  • Message Observers: Track message states like seen, delivered, and reactions in real-time.

Getting Started

This project is written with Locality Social Cloud. To use it, you must have a Social Cloud Developer Account and obtain a secret for your app.

Write

flutter pub add locality_social_cloud
flutter pub add locality_social_cloud_chat
flutter pub get

to import the package. At some point, register your app secret and log your user in to the Locality Social Cloud.

Configure Locality Social Cloud

Obtain your app-ID and app secret from your and write

LocalitySocialCloud.configure(app_id: 'YOUR APP ID', app_secret: 'YOUR APP SECRET');

Then, run flutter pub get to install the package.

Import the Library

import 'package:locality_social_cloud_chat/locality_social_cloud_chat.dart';

Example Usage

1. Initialize Direct Messages Chat

Create an instance of DirectMessagesChat for one-on-one messaging.

DirectMessagesChat chat = await DirectMessagesFacade.getTargetUserChat(
      loggedInUser,
      targetUser
  );

2. Sending a Message

Send a new message to the chat by providing the message payload.

chat.sendMessage({
  'content': 'Hello, this is a message!',
});

You can listen to state updates like this:

chat.addListener(() {
    ...
});

This is throttled, it means it will at max 120 times per second be called and only if new state is available. You can use it like a Provider to easily integrate with your UI. If you want certain events to only happen after synchronization you can use the Timeline from locality_social_cloud like

chat.timeline.whenSynchronized(() {
    for (var chatMessage in chat.chatMessages) {
      String messageUuid = chatMessage.payload['message_uuid'];
      ....
    }
  });

3. Adding a Reaction to a Message

React to a specific message using its unique message ID.

chat.reactToMessage('message_uuid_123', 'like');

4. Tracking Message States

You can monitor whether a message has been delivered or seen by subscribing to its MessageObserver.

MessageObserver chatMessageObserver = chat.messageObserversByChatMessageUUID[messageUuid]!;
if (!messageObserver.seen) {
    print('Message not seen yet');
}
messageObserver.addListener((){
    // Will be called when the state changes
    if (messageObserver.seen) {
        print('Message seen');
    }
});

Use this inside of

chat.timeline.whenSynchronized(() {
    ...
});

If you have special message types that should trigger other things like photo_messages triggering a photo download, you could use

chat.whenMessageOfTypeReceived('photo_message', (messageObserver) {
    
});

5. Handling Group Chat Invitations

Invite a user to a group chat or accept an invitation:

chat.inviteToGroupChat('Cool Group', 'group_uuid_456', 'group_topic', BigInt.from(123456));
chat.acceptGroupChatInvitation('message_uuid_789', 'group_uuid_456');

Use also an invitation to create a group chat.

The GroupChats class will hold the group chats yielded from accepted invitations.

GroupChats.getInstance().addListener(() {
    List<GroupChat> groupChats = GroupChats.getInstance().groupChats;
    for(GroupChat groupChat in groupChats) {
      print("We are connected to the groupchat ... "+groupChat.title);
    }
  });

Event Handling

The DirectMessagesChat class listens for various chat-related events (message added, reacted, seen, delivered, etc.). You can handle these events by implementing custom actions.

Entering and Leaving a Chat

When a user enters or leaves a chat, you can influence whether they’ve viewed messages.

chat.enterChat();  // Marks all messages as seen.
chat.leaveChat();  // Marks the chat as unviewed.