| 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 |