locality_core 1.0.4 copy "locality_core: ^1.0.4" to clipboard
locality_core: ^1.0.4 copied to clipboard

Realtime state synchronization across devices, powered by the Locality Social Cloud.

example/locality_core_example.dart

import 'dart:async';
import 'dart:convert';
import 'dart:math';

import 'package:crypto/crypto.dart';
import 'package:locality_core/locality_core.dart';
import 'package:locality_core/src/auth/exception/locality_authentication_exception.dart';
import 'package:locality_core/src/auth/data/user/authenticated_session_user.dart';
import 'package:locality_core/src/auth/data/user/public_user.dart';
import 'package:m511chacha20/chacha20_key.dart';

void main() async {
  late LocalitySocialCloud cloud;
  try {
    cloud = await LocalitySocialCloud.startTest(
        userCredentials: UserCredentials("SocialCloudDev", "123456"),
        developerCredentials: DeveloperCredentials(
            realmId: "public_test_realm",
            realmSecret: "Zmbw951fsRPhCPake6rtBWc8YPKvUYChi45gN14znek="),
        isRegistration: false);
  } on LocalityAuthenticationException catch (exception) {
    rethrow;
  } catch (unexpectedError) {
    rethrow;
  }

  final String chatPartner = "SocialCloudDev";
  AuthenticatedSessionUser authenticatedSessionUser = cloud.getLoggedInUser();

  KeyExchangeLobby findFriends = KeyExchangeLobby();
  await LocalitySocialCloud.supervise(
      pubSub: findFriends, key: ChaCha20Key.fromString("Hello World"));

  if (!findFriends.containsUserById(authenticatedSessionUser.publicUser.id)) {
    findFriends.announcePresence(authenticatedSessionUser);
  }

  if (findFriends.containsUserById(chatPartner)) {
    ChaCha20Key? sharedKey =
        await findFriends.getSharedKey(authenticatedSessionUser, chatPartner);

    SimpleMessageExample messageExample =
        SimpleMessageExample(authenticatedSessionUser, chatPartner);

    await LocalitySocialCloud.supervise(pubSub: messageExample, key: sharedKey);

    GreenTick greenTick = GreenTick();
    Broadcast broadcast = messageExample.sendMessage(authenticatedSessionUser,
        "Hello Malte. I am a new Locality Social Cloud developer!!");
    broadcast.addObserver(greenTick);
    await greenTick.future;

    messageExample.printAllMessages();
  }
}

class GreenTick implements BroadcastObserver {
  final Completer<void> _completer = Completer<void>();

  Future<void> get future => _completer.future;

  @override
  void onBroadcastChanged(Broadcast broadcast) {
    if (broadcast.status == BroadcastStatus.confirmed) {
      if (!_completer.isCompleted) {
        _completer.complete();
      }
    }
  }
}

class KeyExchangeLobby with PubSub {
  Map<String, String> publicKeyByUserId = {};
  int x = 546546;

  @override
  String getTopic() {
    return "test:key-exchange-" + x.toString();
  }

  @override
  void onReceive(Broadcast localityEvent) {
    Map<String, dynamic> payload = localityEvent.getPayload();

    switch (localityEvent.event) {
      case "here":
        publicKeyByUserId[payload["userId"]] = payload["publicKey"];
        break;
    }
  }

  void announcePresence(AuthenticatedSessionUser authenticateUser) {
    send("here", {
      "userId": authenticateUser.publicUser.id,
      "publicKey": authenticateUser.publicUser.publicKey
    });
  }

  bool containsUserById(String userId) {
    return publicKeyByUserId.containsKey(userId);
  }

  Future<ChaCha20Key?> getSharedKey(
      AuthenticatedSessionUser sessionUser, String targetUserId) async {
    if (!containsUserById(targetUserId)) {
      return null;
    }
    String publicKey = publicKeyByUserId[targetUserId]!;
    return await sessionUser
        .computeKeyForIsolate(PublicUser(targetUserId, publicKey));
  }
}

class SimpleMessage {
  final String userId;
  final String message;

  SimpleMessage({
    required this.userId,
    required this.message,
  });

  Map<String, dynamic> toMap() {
    return {
      'userId': userId,
      'message': message,
    };
  }

  factory SimpleMessage.fromMap(Map<String, dynamic> map) {
    return SimpleMessage(
      userId: map['userId'] ?? '',
      message: map['message'] ?? '',
    );
  }
}

class SimpleMessageExample with PubSub {
  List<SimpleMessage> messages = [];
  late String topic;

  SimpleMessageExample(
      AuthenticatedSessionUser sessionUser, String targetUserId) {
    // Ensure both users compoute the same topic name
    bool targetUserIdIsBigger =
        sessionUser.publicUser.id.compareTo(targetUserId) > 0;
    String textToHash = targetUserIdIsBigger
        ? sessionUser.publicUser.id + targetUserId
        : targetUserId + sessionUser.publicUser.id;
    topic = sha256.convert(utf8.encode(textToHash)).toString();
  }
  int x = 546546;

  @override
  String getTopic() {
    return 'test:$topic-messages-' + x.toString();
    ;
  }

  @override
  void onReceive(Broadcast localityEvent) {
    switch (localityEvent.event) {
      case "message":
        messages.add(SimpleMessage.fromMap(localityEvent.getPayload()));
        break;
    }
  }

  Broadcast sendMessage(AuthenticatedSessionUser authenticateUser, String text,
      {BroadcastObserver? observer}) {
    return send(
        "message",
        SimpleMessage(userId: authenticateUser.publicUser.id, message: text)
            .toMap());
  }

  void printAllMessages() {
    print("---------------------------------------------------------------");
    for (var msg in messages) {
      print('${msg.userId}: ${msg.message}');
    }
  }
}
0
likes
160
points
151
downloads

Documentation

API reference

Publisher

verified publisherlocality.media

Weekly Downloads

Realtime state synchronization across devices, powered by the Locality Social Cloud.

Homepage
Repository

License

BSD-3-Clause (license)

Dependencies

argon2_web, crypto, http, m511chacha20, phoenix_socket, uuid

More

Packages that depend on locality_core