fetchOriginalContent method

Future<void> fetchOriginalContent(
  1. String originalId,
  2. String msgId
)

Implementation

Future<void> fetchOriginalContent(String originalId, String msgId) async {
  RoomMessage roomMsg;
  try {
    roomMsg = await timeline.getMessage(originalId);
  } catch (e, s) {
    _log.severe(
      'Failing to load reference $msgId (from $originalId)',
      e,
      s,
    );
    return;
  }

  // reply is allowed for only EventItem not VirtualItem
  // user should be able to get original event as RoomMessage
  RoomEventItem orgEventItem = roomMsg.eventItem()!;
  EventSendState? eventState = orgEventItem.sendState();
  String eventType = orgEventItem.eventType();
  Map<String, dynamic> repliedToContent = {'eventState': eventState};
  types.Message? repliedTo;
  switch (eventType) {
    case 'm.policy.rule.room':
    case 'm.policy.rule.server':
    case 'm.policy.rule.user':
    case 'm.room.aliases':
    case 'm.room.avatar':
    case 'm.room.canonical_alias':
    case 'm.room.create':
    case 'm.room.encryption':
    case 'm.room.guest.access':
    case 'm.room.history_visibility':
    case 'm.room.join.rules':
    case 'm.room.name':
    case 'm.room.pinned_events':
    case 'm.room.power_levels':
    case 'm.room.server_acl':
    case 'm.room.third_party_invite':
    case 'm.room.tombstone':
    case 'm.room.topic':
    case 'm.space.child':
    case 'm.space.parent':
      break;
    case 'm.room.encrypted':
      repliedTo = types.CustomMessage(
        author: types.User(id: orgEventItem.sender()),
        createdAt: orgEventItem.originServerTs(),
        id: roomMsg.uniqueId(),
        metadata: {
          'itemType': 'event',
          'eventType': eventType,
        },
      );
      break;
    case 'm.room.redaction':
      repliedTo = types.CustomMessage(
        author: types.User(id: orgEventItem.sender()),
        createdAt: orgEventItem.originServerTs(),
        id: roomMsg.uniqueId(),
        metadata: {
          'itemType': 'event',
          'eventType': eventType,
        },
      );
      break;
    case 'm.call.answer':
    case 'm.call.candidates':
    case 'm.call.hangup':
    case 'm.call.invite':
      break;
    case 'm.room.message':
      String? orgMsgType = orgEventItem.msgType();
      switch (orgMsgType) {
        case 'm.text':
          MsgContent? msgContent = orgEventItem.msgContent();
          if (msgContent != null) {
            String body = msgContent.body();
            repliedToContent = {
              'content': body,
              'messageLength': body.length,
            };
            repliedTo = types.TextMessage(
              author: types.User(id: orgEventItem.sender()),
              id: originalId,
              createdAt: orgEventItem.originServerTs(),
              text: body,
              metadata: repliedToContent,
            );
          }
          break;
        case 'm.image':
          MsgContent? msgContent = orgEventItem.msgContent();
          if (msgContent != null) {
            final convo = await ref.read(chatProvider(roomId).future);
            if (convo == null) {
              throw RoomNotFound();
            }
            convo.mediaBinary(originalId, null).then((data) {
              repliedToContent['base64'] = base64Encode(data.asTypedList());
            });
            repliedTo = types.ImageMessage(
              author: types.User(id: orgEventItem.sender()),
              id: originalId,
              createdAt: orgEventItem.originServerTs(),
              name: msgContent.body(),
              size: msgContent.size() ?? 0,
              uri: msgContent.source()!.url(),
              width: msgContent.width()?.toDouble() ?? 0,
              metadata: repliedToContent,
            );
          }
          break;
        case 'm.audio':
          MsgContent? msgContent = orgEventItem.msgContent();
          if (msgContent != null) {
            final convo = await ref.read(chatProvider(roomId).future);
            if (convo == null) {
              throw RoomNotFound();
            }
            convo.mediaBinary(originalId, null).then((data) {
              repliedToContent['content'] = base64Encode(data.asTypedList());
            });
            repliedTo = types.AudioMessage(
              author: types.User(id: orgEventItem.sender()),
              id: originalId,
              createdAt: orgEventItem.originServerTs(),
              name: msgContent.body(),
              duration: Duration(seconds: msgContent.duration() ?? 0),
              size: msgContent.size() ?? 0,
              uri: msgContent.source()!.url(),
              metadata: repliedToContent,
            );
          }
          break;
        case 'm.video':
          MsgContent? msgContent = orgEventItem.msgContent();
          if (msgContent != null) {
            final convo = await ref.read(chatProvider(roomId).future);
            if (convo == null) {
              throw RoomNotFound();
            }
            convo.mediaBinary(originalId, null).then((data) {
              repliedToContent['content'] = base64Encode(data.asTypedList());
            });
            repliedTo = types.VideoMessage(
              author: types.User(id: orgEventItem.sender()),
              id: originalId,
              createdAt: orgEventItem.originServerTs(),
              name: msgContent.body(),
              size: msgContent.size() ?? 0,
              uri: msgContent.source()!.url(),
              metadata: repliedToContent,
            );
          }
          break;
        case 'm.file':
          MsgContent? msgContent = orgEventItem.msgContent();
          if (msgContent != null) {
            repliedToContent = {
              'content': msgContent.body(),
            };
            repliedTo = types.FileMessage(
              author: types.User(id: orgEventItem.sender()),
              id: originalId,
              createdAt: orgEventItem.originServerTs(),
              name: msgContent.body(),
              size: msgContent.size() ?? 0,
              uri: msgContent.source()!.url(),
              metadata: repliedToContent,
            );
          }
          break;
        case 'm.sticker':
          // user can’t do any action about sticker message
          break;
      }
  }

  final messages = state.messages;
  int index = messages.indexWhere((x) => x.id == msgId);
  if (index != -1 && repliedTo != null) {
    replaceMessageAt(
      index,
      messages[index].copyWith(repliedMessage: repliedTo),
    );
  }
}