[Lists] Fix send status

This commit is contained in:
Christian Pauly 2019-06-26 16:36:34 +02:00
parent c3967419e6
commit 41d8b91f87
4 changed files with 123 additions and 42 deletions

View file

@ -165,46 +165,66 @@ class Room {
type: "PUT", type: "PUT",
action: "/client/r0/rooms/${id}/send/m.room.message/$txid", action: "/client/r0/rooms/${id}/send/m.room.message/$txid",
data: {"msgtype": "m.text", "body": message}); data: {"msgtype": "m.text", "body": message});
if (res["errcode"] == "M_LIMIT_EXCEEDED") if (res is ErrorResponse) client.connection.onError.add(res);
client.connection.onError.add(res["error"]);
return res; return res;
} }
Future<String> sendTextEvent(String message) async { Future<String> sendTextEvent(String message, {String txid = null}) async {
final String type = "m.room.message"; final String type = "m.room.message";
String messageID;
final int now = DateTime.now().millisecondsSinceEpoch; final int now = DateTime.now().millisecondsSinceEpoch;
final String messageID = "msg$now"; if (txid == null) {
messageID = "msg$now";
} else
messageID = txid;
// Display a *sending* event and store it.
EventUpdate eventUpdate = EventUpdate eventUpdate =
EventUpdate(type: "timeline", roomID: id, eventType: type, content: { EventUpdate(type: "timeline", roomID: id, eventType: type, content: {
"type": type, "type": type,
"id": messageID, "id": null,
"sender": client.userID, "sender": client.userID,
"status": 0, "status": 0,
"origin_server_ts": now, "origin_server_ts": now,
"content": { "content": {
"msgtype": "m.text", "msgtype": "m.text",
"body": message, "body": message,
"txid": messageID,
} }
}); });
client.connection.onEvent.add(eventUpdate); client.connection.onEvent.add(eventUpdate);
await client.store.transaction(() { await client.store?.transaction(() {
client.store.storeEventUpdate(eventUpdate); client.store.storeEventUpdate(eventUpdate);
}); });
// Send the text and on success, store and display a *sent* event.
final dynamic res = await sendText(message, txid: messageID); final dynamic res = await sendText(message, txid: messageID);
if (res is ErrorResponse) { if (res is ErrorResponse) {
client.store.db // On error, set status to -1
.rawUpdate("UPDATE Events SET status=-1 WHERE id=?", [messageID]); eventUpdate.content["status"] = -1;
client.connection.onEvent.add(eventUpdate);
client.store?.db
?.rawUpdate("UPDATE Events SET status=-1 WHERE id=?", [messageID]);
} else { } else {
final String newEventID = res["event_id"]; final String newEventID = res["event_id"];
final List<Map<String, dynamic>> event = await client.store.db eventUpdate.content["status"] = 1;
eventUpdate.content["id"] = newEventID;
client.connection.onEvent.add(eventUpdate);
// Store the result in database
if (client.store != null) {
final List<Map<String, dynamic>> eventQuery = await client.store.db
.rawQuery("SELECT * FROM Events WHERE id=?", [newEventID]); .rawQuery("SELECT * FROM Events WHERE id=?", [newEventID]);
if (event.length > 0) { if (eventQuery.length > 0) {
client.store.db.rawDelete("DELETE FROM Events WHERE id=?", [messageID]); client.store.db
.rawDelete("DELETE FROM Events WHERE id=?", [messageID]);
} else { } else {
client.store.db.rawUpdate("UPDATE Events SET id=?, status=1 WHERE id=?", client.store.db.rawUpdate(
"UPDATE Events SET id=?, status=1 WHERE id=?",
[newEventID, messageID]); [newEventID, messageID]);
} }
}
return newEventID; return newEventID;
} }
return null; return null;

View file

@ -37,6 +37,8 @@ class Timeline {
final onTimelineUpdateCallback onUpdate; final onTimelineUpdateCallback onUpdate;
final onTimelineInsertCallback onInsert; final onTimelineInsertCallback onInsert;
Set<String> waitToReplace = {};
StreamSubscription<EventUpdate> sub; StreamSubscription<EventUpdate> sub;
Timeline({this.room, this.events, this.onUpdate, this.onInsert}) { Timeline({this.room, this.events, this.onUpdate, this.onInsert}) {
@ -47,6 +49,25 @@ class Timeline {
try { try {
if (eventUpdate.roomID != room.id) return; if (eventUpdate.roomID != room.id) return;
if (eventUpdate.type == "timeline" || eventUpdate.type == "history") { if (eventUpdate.type == "timeline" || eventUpdate.type == "history") {
// Is this event already in the timeline?
if (eventUpdate.content["status"] == 1 ||
eventUpdate.content["status"] == -1 ||
waitToReplace.contains(eventUpdate.content["id"])) {
int i;
for (i = 0; i < events.length; i++) {
if (events[i].content.containsKey("txid") &&
events[i].content["txid"] ==
eventUpdate.content["content"]["txid"] ||
events[i].id == eventUpdate.content["id"]) break;
}
if (i < events.length) {
events[i] = Event.fromJson(eventUpdate.content, room);
if (eventUpdate.content["content"]["txid"] is String)
waitToReplace.add(eventUpdate.content["id"]);
else
waitToReplace.remove(eventUpdate.content["id"]);
}
} else {
if (!eventUpdate.content.containsKey("id")) if (!eventUpdate.content.containsKey("id"))
eventUpdate.content["id"] = eventUpdate.content["event_id"]; eventUpdate.content["id"] = eventUpdate.content["event_id"];
@ -62,6 +83,7 @@ class Timeline {
events.insert(0, newEvent); events.insert(0, newEvent);
if (onInsert != null) onInsert(0); if (onInsert != null) onInsert(0);
} }
}
sortAndUpdate(); sortAndUpdate();
} catch (e) { } catch (e) {
print("[WARNING] (_handleEventUpdate) ${e.toString()}"); print("[WARNING] (_handleEventUpdate) ${e.toString()}");

View file

@ -376,7 +376,12 @@ class FakeMatrixApi extends MockClient {
}, },
"/client/r0/rooms/!localpart:server.abc/read_markers": (var reqI) => {}, "/client/r0/rooms/!localpart:server.abc/read_markers": (var reqI) => {},
}, },
"PUT": {}, "PUT": {
"/client/r0/rooms/!1234:example.com/send/m.room.message/1234":
(var reqI) => {
"event_id": "42",
},
},
"DELETE": { "DELETE": {
"/unknown/token": (var req) => {"errcode": "M_UNKNOWN_TOKEN"}, "/unknown/token": (var req) => {"errcode": "M_UNKNOWN_TOKEN"},
}, },

View file

@ -27,6 +27,7 @@ import 'package:famedlysdk/src/Room.dart';
import 'package:famedlysdk/src/Timeline.dart'; import 'package:famedlysdk/src/Timeline.dart';
import 'package:famedlysdk/src/sync/EventUpdate.dart'; import 'package:famedlysdk/src/sync/EventUpdate.dart';
import 'package:famedlysdk/src/utils/ChatTime.dart'; import 'package:famedlysdk/src/utils/ChatTime.dart';
import 'FakeMatrixApi.dart';
void main() { void main() {
/// All Tests related to the MxContent /// All Tests related to the MxContent
@ -36,9 +37,9 @@ void main() {
int updateCount = 0; int updateCount = 0;
List<int> insertList = []; List<int> insertList = [];
test("Create", () async { Client client = Client("testclient", debug: true);
Client client = Client("testclient"); client.connection.httpClient = FakeMatrixApi();
client.homeserver = "https://testserver.abc"; client.homeserver = "https://fakeServer.notExisting";
Room room = Room(id: roomID, client: client); Room room = Room(id: roomID, client: client);
Timeline timeline = Timeline( Timeline timeline = Timeline(
@ -51,6 +52,7 @@ void main() {
insertList.add(insertID); insertList.add(insertID);
}); });
test("Create", () async {
client.connection.onEvent.add(EventUpdate( client.connection.onEvent.add(EventUpdate(
type: "timeline", type: "timeline",
roomID: roomID, roomID: roomID,
@ -91,5 +93,37 @@ void main() {
expect(timeline.events[0].getBody(), "Testcase"); expect(timeline.events[0].getBody(), "Testcase");
expect(timeline.events[0].time > timeline.events[1].time, true); expect(timeline.events[0].time > timeline.events[1].time, true);
}); });
test("Send message", () async {
room.sendTextEvent("test", txid: "1234");
await new Future.delayed(new Duration(milliseconds: 50));
expect(updateCount, 4);
expect(insertList, [0, 0, 0]);
expect(timeline.events[0].content["txid"], "1234");
expect(timeline.events[0].id, "42");
expect(timeline.events[0].status, 1);
client.connection.onEvent.add(EventUpdate(
type: "timeline",
roomID: roomID,
eventType: "m.room.message",
content: {
"type": "m.room.message",
"content": {"msgtype": "m.text", "body": "test"},
"sender": "@alice:example.com",
"status": 2,
"id": "42",
"origin_server_ts": DateTime.now().millisecondsSinceEpoch
}));
await new Future.delayed(new Duration(milliseconds: 50));
expect(updateCount, 5);
expect(insertList, [0, 0, 0]);
expect(timeline.events[0].id, "42");
expect(timeline.events[0].status, 2);
});
}); });
} }