From 8e7eaac9d2dcc3e26aa1d4ed11df296df0d16877 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Wed, 7 Aug 2019 09:52:36 +0200 Subject: [PATCH] [Event] New event classes --- lib/src/Event.dart | 207 +++++++++--------------------------------- lib/src/RawEvent.dart | 163 +++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+), 163 deletions(-) create mode 100644 lib/src/RawEvent.dart diff --git a/lib/src/Event.dart b/lib/src/Event.dart index c5fb1ab..7f969ff 100644 --- a/lib/src/Event.dart +++ b/lib/src/Event.dart @@ -21,37 +21,14 @@ * along with famedlysdk. If not, see . */ -import 'dart:convert'; - -import 'package:famedlysdk/src/Client.dart'; import 'package:famedlysdk/src/sync/EventUpdate.dart'; import 'package:famedlysdk/src/utils/ChatTime.dart'; import './Room.dart'; -import './User.dart'; - -/// A single Matrix event, e.g. a message in a chat. -class Event { - /// The Matrix ID for this event in the format '$localpart:server.abc'. - final String id; - - /// The room this event belongs to. - final Room room; - - /// The time this event has received at the server. - final ChatTime time; - - /// The user who has sent this event. - final User sender; - - /// The user who is the target of this event e.g. for a m.room.member event. - final User stateKey; - - /// The type of this event. Mostly this is 'timeline'. - final String environment; - - Event replyEvent; +import './RawEvent.dart'; +/// Defines a timeline event for a room. +class Event extends RawEvent { /// The status of this event. /// -1=ERROR /// 0=SENDING @@ -59,20 +36,44 @@ class Event { /// 2=RECEIVED int status; - /// The json payload of the content. The content highly depends on the type. - final Map content; - Event( - this.id, - this.sender, - this.time, { - this.room, - this.stateKey, - this.status = 2, - this.environment, - this.content, - this.replyEvent, - }); + {this.status, + dynamic content, + String typeKey, + String eventId, + String roomId, + String sender, + ChatTime time, + dynamic unsigned, + Room room}) + : super( + content: content, + typeKey: typeKey, + eventId: eventId, + roomId: roomId, + sender: sender, + time: time, + unsigned: unsigned, + room: room); + + /// Get a State event from a table row or from the event stream. + factory Event.fromJson( + Map jsonPayload, int status, Room room) { + final Map content = + RawEvent.getMapFromPayload(jsonPayload['content']); + final Map unsigned = + RawEvent.getMapFromPayload(jsonPayload['unsigned']); + return Event( + status: status, + content: content, + typeKey: jsonPayload['type'], + eventId: jsonPayload['event_id'], + roomId: jsonPayload['room_id'], + sender: jsonPayload['sender'], + time: ChatTime(jsonPayload['origin_server_ts']), + unsigned: unsigned, + room: room); + } /// Returns the body of this event if it has a body. String get text => content["body"] ?? ""; @@ -84,89 +85,7 @@ class Event { String getBody() { if (text != "") return text; if (formattedText != "") return formattedText; - return "*** Unable to parse Content ***"; - } - - /// Get the real type. - EventTypes get type { - switch (environment) { - case "m.room.avatar": - return EventTypes.RoomAvatar; - case "m.room.name": - return EventTypes.RoomName; - case "m.room.topic": - return EventTypes.RoomTopic; - case "m.room.Aliases": - return EventTypes.RoomAliases; - case "m.room.canonical_alias": - return EventTypes.RoomCanonicalAlias; - case "m.room.create": - return EventTypes.RoomCreate; - case "m.room.join_rules": - return EventTypes.RoomJoinRules; - case "m.room.member": - return EventTypes.RoomMember; - case "m.room.power_levels": - return EventTypes.RoomPowerLevels; - case "m.room.guest_access": - return EventTypes.GuestAccess; - case "m.room.history_visibility": - return EventTypes.HistoryVisibility; - case "m.room.message": - switch (content["msgtype"] ?? "m.text") { - case "m.text": - if (content.containsKey("m.relates_to")) { - return EventTypes.Reply; - } - return EventTypes.Text; - case "m.notice": - return EventTypes.Notice; - case "m.emote": - return EventTypes.Emote; - case "m.image": - return EventTypes.Image; - case "m.video": - return EventTypes.Video; - case "m.audio": - return EventTypes.Audio; - case "m.file": - return EventTypes.File; - case "m.location": - return EventTypes.Location; - } - } - return EventTypes.Unknown; - } - - /// Generate a new Event object from a json string, mostly a table row. - static Event fromJson(Map jsonObj, Room room, - {User senderUser, User stateKeyUser}) { - Map content = jsonObj["content"]; - - if (content == null && jsonObj["content_json"] != null) - try { - content = json.decode(jsonObj["content_json"]); - } catch (e) { - if (room.client.debug) { - print("jsonObj decode of event content failed: ${e.toString()}"); - } - content = {}; - } - else if (content == null) content = {}; - - if (senderUser == null) senderUser = User.fromJson(jsonObj, room); - if (stateKeyUser == null) stateKeyUser = User(jsonObj["state_key"]); - - return Event( - jsonObj["event_id"] ?? jsonObj["id"], - senderUser, - ChatTime(jsonObj["origin_server_ts"]), - stateKey: stateKeyUser, - environment: jsonObj["type"], - status: jsonObj["status"] ?? 2, - content: content, - room: room, - ); + return "$type"; } /// Removes this event if the status is < 1. This event will just be removed @@ -175,14 +94,14 @@ class Event { if (status < 1) { if (room.client.store != null) await room.client.store.db - .rawDelete("DELETE FROM Events WHERE id=?", [id]); + .rawDelete("DELETE FROM Events WHERE id=?", [eventId]); room.client.connection.onEvent.add(EventUpdate( roomID: room.id, type: "timeline", - eventType: environment, + eventType: typeKey, content: { - "event_id": id, + "event_id": eventId, "status": -2, "content": {"body": "Removed..."} })); @@ -198,42 +117,4 @@ class Event { final String eventID = await room.sendTextEvent(text, txid: txid); return eventID; } - - @Deprecated("Use [client.store.getEventList(Room room)] instead!") - static Future> getEventList(Client matrix, Room room) async { - List eventList = await matrix.store.getEventList(room); - return eventList; - } } - -enum EventTypes { - Text, - Emote, - Notice, - Image, - Video, - Audio, - File, - Location, - Reply, - RoomAliases, - RoomCanonicalAlias, - RoomCreate, - RoomJoinRules, - RoomMember, - RoomPowerLevels, - RoomName, - RoomTopic, - RoomAvatar, - GuestAccess, - HistoryVisibility, - Unknown, -} - -final Map StatusTypes = { - "REMOVE": -2, - "ERROR": -1, - "SENDING": 0, - "SENT": 1, - "RECEIVED": 2, -}; diff --git a/lib/src/RawEvent.dart b/lib/src/RawEvent.dart new file mode 100644 index 0000000..153463d --- /dev/null +++ b/lib/src/RawEvent.dart @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * 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 . + */ + +import 'dart:convert'; +import 'package:meta/meta.dart'; +import 'package:famedlysdk/src/utils/ChatTime.dart'; +import './Room.dart'; + +class RawEvent { + /// The Matrix ID for this event in the format '$localpart:server.abc'. Please not + /// that account data, presence and other events may not have an eventId. + final String eventId; + + /// The json payload of the content. The content highly depends on the type. + final Map content; + + /// The type String of this event. For example 'm.room.message'. + final String typeKey; + + /// The ID of the room this event belongs to if there is any. Use this to get the room + /// if the [room] is null. + final String roomId; + + /// The user who has sent this event if it is not a global account data event. + final String sender; + + /// The time this event has received at the server. May be null for events like + /// account data. + final ChatTime time; + + /// Optional additional content for this event. + final Map unsigned; + + /// The room this event belongs to. May be null. + final Room room; + + RawEvent( + {@required this.content, + @required this.typeKey, + this.eventId, + this.roomId, + this.sender, + this.time, + this.unsigned, + this.room}); + + static Map getMapFromPayload(dynamic payload) => + payload is String + ? json.decode(payload) + : payload is Map ? payload : null; + + /// Get a State event from a table row or from the event stream. + factory RawEvent.fromJson(Map jsonPayload, Room room) { + final Map content = + getMapFromPayload(jsonPayload['content']); + final Map unsigned = + getMapFromPayload(jsonPayload['unsigned']); + return RawEvent( + content: content, + typeKey: jsonPayload['type'], + eventId: jsonPayload['event_id'], + roomId: jsonPayload['room_id'], + sender: jsonPayload['sender'], + time: ChatTime(jsonPayload['origin_server_ts']), + unsigned: unsigned, + room: room); + } + + /// Get the real type. + EventTypes get type { + switch (typeKey) { + case "m.room.avatar": + return EventTypes.RoomAvatar; + case "m.room.name": + return EventTypes.RoomName; + case "m.room.topic": + return EventTypes.RoomTopic; + case "m.room.Aliases": + return EventTypes.RoomAliases; + case "m.room.canonical_alias": + return EventTypes.RoomCanonicalAlias; + case "m.room.create": + return EventTypes.RoomCreate; + case "m.room.join_rules": + return EventTypes.RoomJoinRules; + case "m.room.member": + return EventTypes.RoomMember; + case "m.room.power_levels": + return EventTypes.RoomPowerLevels; + case "m.room.guest_access": + return EventTypes.GuestAccess; + case "m.room.history_visibility": + return EventTypes.HistoryVisibility; + case "m.room.message": + switch (content["msgtype"] ?? "m.text") { + case "m.text": + if (content.containsKey("m.relates_to")) { + return EventTypes.Reply; + } + return EventTypes.Text; + case "m.notice": + return EventTypes.Notice; + case "m.emote": + return EventTypes.Emote; + case "m.image": + return EventTypes.Image; + case "m.video": + return EventTypes.Video; + case "m.audio": + return EventTypes.Audio; + case "m.file": + return EventTypes.File; + case "m.location": + return EventTypes.Location; + } + } + return EventTypes.Unknown; + } +} + +enum EventTypes { + Text, + Emote, + Notice, + Image, + Video, + Audio, + File, + Location, + Reply, + RoomAliases, + RoomCanonicalAlias, + RoomCreate, + RoomJoinRules, + RoomMember, + RoomPowerLevels, + RoomName, + RoomTopic, + RoomAvatar, + GuestAccess, + HistoryVisibility, + Unknown, +}