Locality Social Cloud Chat
locality_social_cloud_chat is a Locality Core based End-to-end-encrypted messaging suite.
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
PubSubmodel. - Group Chats: Invite users to group chats and manage acceptances.
- Efficient UI Updates: Implemented using
ThrottledChangeNotifierfor optimized state updates. - Message Observers: Track message states like
seen,delivered, and reactions in real-time.
Getting Started
Check the Locality Core to obtain your app realm and secret.
Write
flutter pub add locality_social_cloud_chat
flutter pub get
to import the package. The class 'LocalitySocialCloudChat' provides your interface.
import 'package:locality_core/locality_core.dart';
import 'package:locality_social_cloud_chat/locality_social_cloud_chat.dart';
It provides these methods:
static void setKeyCache(File cache)
static String getCommonTopicForUsers(PublicUser userA, PublicUser userB)
static Future<KeyExchangeLobby> getKeyExchangeLobby(String topic)
static Future<MessagingTopic> getSubscribedTopic(TopicSubscription subscription, ChatMessageFactory chatMessageFactory)
static Future<MessagingTopic> getGroupChat(GroupChatInvitation groupChatInvite, ChatMessageFactory chatMessageFactory)
static Future<MessagingSubscriptions> getUserMessageTopicSubscriptions({required AuthenticatedSessionUser user, String? subTopic, ChaCha20Key? chaChaKey})
static Future<MessagingTopic> getUserChat(AuthenticatedSessionUser loggedInUser, PublicUser publicUser, ChatMessageFactory chatMessageFactory)
Full example
/// A concrete implementation of [ChatMessageFactory] that instantiates [SimpleMessage] from payloads.
class TestChatMessageFactory implements ChatMessageFactory {
@override
ChatMessage createFrom(String id, Map<String, dynamic> payload) {
payload['id'] = id;
return SimpleMessage.fromMap(payload);
}
}
void main() async {
LocalitySocialCloud cloud = await LocalitySocialCloud.startTest(
userCredentials: UserCredentials("userId", "password"),
developerCredentials: DeveloperCredentials(
realmId: "ptr2",
realmSecret: "h3w1uzXhmHc4JvZi6ZE6bGXlPPISH/t26Pb6vtGzffE="
),
isRegistration: true
);
AuthenticatedSessionUser authenticatedSessionUser = cloud.getLoggedInUser();
LocalitySocialCloudChat localitySocialCloudChat;
KeyExchangeLobby keyExchangeLobby = await LocalitySocialCloudChat.getKeyExchangeLobby("hello");
if ( !keyExchangeLobby.containsMe(authenticatedSessionUser) ) {
keyExchangeLobby.announcePresence(authenticatedSessionUser);
}
// We want to message this user
PublicUser? klaus = keyExchangeLobby.getUserById("KLAUS");
if ( klaus != null ) {
// Klaus announced his presence, so we can message him
MessagingTopic messagingTopic = await LocalitySocialCloudChat.getUserChat(authenticatedSessionUser, klaus, TestChatMessageFactory());
messagingTopic.sendMessage(SimpleMessage(user: authenticatedSessionUser, message: "HELLO BONJOUR KLAUS"));
}
MessagingSubscriptions messagingSubscriptions = await LocalitySocialCloudChat.getUserMessageTopicSubscriptions(user: authenticatedSessionUser);
messagingSubscriptions.subscriptions.values.forEach((subscription) =>
// Will connect to all messaging topics
LocalitySocialCloudChat.getSubscribedTopic(subscription, TestChatMessageFactory())
);
}
Libraries
- model/dto/chat_event_fields
- model/dto/dtos
- model/dto/events/group_chat_invitation
- model/dto/events/message_deleted_event
- model/dto/events/message_reacted_event
- model/dto/events/messages_seen_event
- model/dto/events/topic_subscription
- model/framework/chat_message
- model/framework/chat_message_factory
- model/framework/green_tick
- model/framework/message_list
- model/throttled_change_notifier
- model/topic/key_exchange_lobby
- model/topic/messaging_subscriptions
- model/topic/messaging_topic