Event constructor

Event({
  1. EventStatus status = defaultStatus,
  2. required Map<String, dynamic> content,
  3. required String type,
  4. required String eventId,
  5. required String senderId,
  6. required DateTime originServerTs,
  7. Map<String, dynamic>? unsigned,
  8. Map<String, dynamic>? prevContent,
  9. String? stateKey,
  10. required Room room,
  11. SDNEvent? originalSource,
})

Implementation

Event({
  this.status = defaultStatus,
  required Map<String, dynamic> content,
  required String type,
  required String eventId,
  required String senderId,
  required DateTime originServerTs,
  Map<String, dynamic>? unsigned,
  Map<String, dynamic>? prevContent,
  String? stateKey,
  required this.room,
  SDNEvent? originalSource,
})  : _originalSource = originalSource,
      super(
        content: content,
        type: type,
        eventId: eventId,
        senderId: senderId,
        originServerTs: originServerTs,
        roomId: room.id,
      ) {
  this.eventId = eventId;
  this.unsigned = unsigned;
  // synapse unfortunately isn't following the spec and tosses the prev_content
  // into the unsigned block.
  // Currently we are facing a very strange bug in web which is impossible to debug.
  // It may be because of this line so we put this in try-catch until we can fix it.
  try {
    this.prevContent = (prevContent != null && prevContent.isNotEmpty)
        ? prevContent
        : (unsigned != null &&
                unsigned.containsKey('prev_content') &&
                unsigned['prev_content'] is Map)
            ? unsigned['prev_content']
            : null;
  } catch (_) {
    // A strange bug in dart web makes this crash
  }
  this.stateKey = stateKey;

  // Mark event as failed to send if status is `sending` and event is older
  // than the timeout. This should not happen with the deprecated Moor
  // database!
  if (status.isSending && room.client.database != null) {
    // Age of this event in milliseconds
    final age = DateTime.now().millisecondsSinceEpoch -
        originServerTs.millisecondsSinceEpoch;

    final room = this.room;
    if (age > room.client.sendMessageTimeoutSeconds * 1000) {
      // Update this event in database and open timelines
      final json = toJson();
      json['unsigned'] ??= <String, dynamic>{};
      json['unsigned'][messageSendingStatusKey] = EventStatus.error.intValue;
      room.client.handleSync(
        SyncUpdate(
          nextBatch: '',
          rooms: RoomsUpdate(
            join: {
              room.id: JoinedRoomUpdate(
                timeline: TimelineUpdate(
                  events: [SDNEvent.fromJson(json)],
                ),
              )
            },
          ),
        ),
      );
    }
  }

  // If this is failed to send and the file is no longer cached, it should be removed!
  if (!status.isSent &&
      {
        MessageTypes.Image,
        MessageTypes.Video,
        MessageTypes.Audio,
        MessageTypes.File,
      }.contains(messageType) &&
      !room.sendingFilePlaceholders.containsKey(eventId)) {
    remove();
  }
}