famedlysdk/lib/src/Event.dart

145 lines
4.6 KiB
Dart
Raw Normal View History

2019-06-09 11:57:33 +00:00
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
2019-06-09 11:57:33 +00:00
*/
2019-08-08 10:51:07 +00:00
import 'package:famedlysdk/src/RoomState.dart';
import 'package:famedlysdk/src/sync/EventUpdate.dart';
2019-06-09 10:16:48 +00:00
import 'package:famedlysdk/src/utils/ChatTime.dart';
2019-10-20 09:44:14 +00:00
import 'package:famedlysdk/src/utils/Receipt.dart';
2019-06-11 09:13:14 +00:00
import './Room.dart';
2019-08-07 07:52:36 +00:00
/// Defines a timeline event for a room.
2019-08-08 10:51:07 +00:00
class Event extends RoomState {
2019-06-11 09:23:57 +00:00
/// The status of this event.
/// -1=ERROR
/// 0=SENDING
/// 1=SENT
/// 2=RECEIVED
int status;
2019-08-29 07:12:55 +00:00
static const int defaultStatus = 2;
Event(
2019-08-29 07:12:55 +00:00
{this.status = defaultStatus,
2019-08-07 07:52:36 +00:00
dynamic content,
String typeKey,
String eventId,
String roomId,
2019-08-07 08:46:59 +00:00
String senderId,
2019-08-07 07:52:36 +00:00
ChatTime time,
dynamic unsigned,
2019-08-08 10:29:09 +00:00
dynamic prevContent,
String stateKey,
2019-08-07 07:52:36 +00:00
Room room})
: super(
content: content,
typeKey: typeKey,
eventId: eventId,
roomId: roomId,
2019-08-07 08:46:59 +00:00
senderId: senderId,
2019-08-07 07:52:36 +00:00
time: time,
unsigned: unsigned,
2019-08-08 10:29:09 +00:00
prevContent: prevContent,
stateKey: stateKey,
2019-08-07 07:52:36 +00:00
room: room);
/// Get a State event from a table row or from the event stream.
2019-08-07 08:46:59 +00:00
factory Event.fromJson(Map<String, dynamic> jsonPayload, Room room) {
2019-08-07 07:52:36 +00:00
final Map<String, dynamic> content =
2019-08-29 09:50:57 +00:00
RoomState.getMapFromPayload(jsonPayload['content']);
2019-08-07 07:52:36 +00:00
final Map<String, dynamic> unsigned =
2019-08-29 09:50:57 +00:00
RoomState.getMapFromPayload(jsonPayload['unsigned']);
2019-08-08 10:29:09 +00:00
final Map<String, dynamic> prevContent =
2019-08-29 09:50:57 +00:00
RoomState.getMapFromPayload(jsonPayload['prev_content']);
2019-08-07 07:52:36 +00:00
return Event(
2019-08-29 07:12:55 +00:00
status: jsonPayload['status'] ?? defaultStatus,
2019-08-07 07:52:36 +00:00
content: content,
typeKey: jsonPayload['type'],
eventId: jsonPayload['event_id'],
roomId: jsonPayload['room_id'],
2019-08-07 08:46:59 +00:00
senderId: jsonPayload['sender'],
2019-08-07 07:52:36 +00:00
time: ChatTime(jsonPayload['origin_server_ts']),
unsigned: unsigned,
2019-08-08 10:29:09 +00:00
prevContent: prevContent,
stateKey: jsonPayload['state_key'],
2019-08-07 07:52:36 +00:00
room: room);
}
2019-06-09 10:16:48 +00:00
2019-06-11 09:23:57 +00:00
/// Returns the body of this event if it has a body.
String get text => content["body"] ?? "";
/// Returns the formatted boy of this event if it has a formatted body.
String get formattedText => content["formatted_body"] ?? "";
/// Use this to get the body.
String getBody() {
2019-06-12 06:22:30 +00:00
if (text != "") return text;
2019-06-12 07:07:07 +00:00
if (formattedText != "") return formattedText;
2019-08-07 07:52:36 +00:00
return "$type";
2019-06-09 10:16:48 +00:00
}
2019-10-20 09:44:14 +00:00
/// Returns a list of [Receipt] instances for this event.
List<Receipt> get receipts {
2019-10-25 08:02:56 +00:00
if (!(room.roomAccountData.containsKey("m.receipt"))) return [];
2019-10-20 09:44:14 +00:00
List<Receipt> receiptsList = [];
2019-10-25 08:02:56 +00:00
for (var entry in room.roomAccountData["m.receipt"].content.entries) {
if (entry.value["event_id"] == eventId)
receiptsList.add(Receipt(
2019-11-15 11:08:43 +00:00
room.getUserByMXIDSync(entry.key), ChatTime(entry.value["ts"])));
2019-10-20 09:44:14 +00:00
}
return receiptsList;
}
/// Removes this event if the status is < 1. This event will just be removed
2019-07-24 08:13:02 +00:00
/// from the database and the timelines. Returns false if not removed.
2019-07-24 08:48:13 +00:00
Future<bool> remove() async {
if (status < 1) {
2019-06-27 08:33:43 +00:00
if (room.client.store != null)
2019-10-02 11:33:01 +00:00
await room.client.store.removeEvent(eventId);
2019-06-27 08:33:43 +00:00
room.client.connection.onEvent.add(EventUpdate(
roomID: room.id,
type: "timeline",
2019-08-07 07:52:36 +00:00
eventType: typeKey,
2019-06-27 08:20:47 +00:00
content: {
2019-08-07 07:52:36 +00:00
"event_id": eventId,
2019-06-27 08:20:47 +00:00
"status": -2,
"content": {"body": "Removed..."}
}));
2019-07-24 08:13:02 +00:00
return true;
}
2019-07-24 08:13:02 +00:00
return false;
}
/// Try to send this event again. Only works with events of status -1.
Future<String> sendAgain({String txid}) async {
if (status != -1) return null;
remove();
final String eventID = await room.sendTextEvent(text, txid: txid);
return eventID;
}
2019-11-26 06:38:44 +00:00
/// Whether the client is allowed to redact this event.
bool get canRedact => senderId == room.client.userID || room.canRedact;
2019-06-09 10:16:48 +00:00
}