1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral <Kitsune-Ral@users.sf.net> |
2 | // SPDX-License-Identifier: LGPL-2.1-or-later |
3 | |
4 | /* |
5 | Example of a Receipt Event: |
6 | { |
7 | "content": { |
8 | "$1435641916114394fHBLK:matrix.org": { |
9 | "m.read": { |
10 | "@rikj:jki.re": { |
11 | "ts": 1436451550453 |
12 | } |
13 | } |
14 | } |
15 | }, |
16 | "room_id": "!KpjVgQyZpzBwvMBsnT:matrix.org", |
17 | "type": "m.receipt" |
18 | } |
19 | */ |
20 | |
21 | #include "receiptevent.h" |
22 | |
23 | #include "../logging_categories_p.h" |
24 | |
25 | using namespace Quotient; |
26 | |
27 | // The library loads the event-ids-to-receipts JSON map into a vector because |
28 | // map lookups are not used and vectors are massively faster. Same goes for |
29 | // de-/serialization of ReceiptsForEvent::receipts. |
30 | // (XXX: would this be generally preferred across CS API JSON maps?..) |
31 | QJsonObject Quotient::toJson(const EventsWithReceipts& ewrs) |
32 | { |
33 | QJsonObject json; |
34 | for (const auto& e : ewrs) { |
35 | QJsonObject receiptsJson; |
36 | for (const auto& r : e.receipts) |
37 | receiptsJson.insert(key: r.userId, |
38 | value: QJsonObject { { "ts"_ls , toJson(val: r.timestamp) } }); |
39 | json.insert(key: e.evtId, value: QJsonObject { { "m.read"_ls , receiptsJson } }); |
40 | } |
41 | return json; |
42 | } |
43 | |
44 | template<> |
45 | EventsWithReceipts Quotient::fromJson(const QJsonObject& json) |
46 | { |
47 | EventsWithReceipts result; |
48 | result.reserve(asize: json.size()); |
49 | for (auto eventIt = json.begin(); eventIt != json.end(); ++eventIt) { |
50 | if (eventIt.key().isEmpty()) { |
51 | qCWarning(EPHEMERAL) |
52 | << "ReceiptEvent has an empty event id, skipping" ; |
53 | qCDebug(EPHEMERAL) << "ReceiptEvent content follows:\n" << json; |
54 | continue; |
55 | } |
56 | const auto reads = |
57 | eventIt.value().toObject().value(key: "m.read"_ls ).toObject(); |
58 | QVector<UserTimestamp> usersAtEvent; |
59 | usersAtEvent.reserve(asize: reads.size()); |
60 | for (auto userIt = reads.begin(); userIt != reads.end(); ++userIt) { |
61 | const auto user = userIt.value().toObject(); |
62 | usersAtEvent.push_back( |
63 | t: { .userId: userIt.key(), .timestamp: fromJson<QDateTime>(jv: user["ts" _ls]) }); |
64 | } |
65 | result.push_back(t: { .evtId: eventIt.key(), .receipts: std::move(usersAtEvent) }); |
66 | } |
67 | return result; |
68 | } |
69 | |