libQuotient
A Qt library for building matrix clients
eventitem.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2018 Kitsune Ral <kitsune-ral@users.sf.net>
2 // SPDX-License-Identifier: LGPL-2.1-or-later
3 
4 #pragma once
5 
6 #include "quotient_common.h"
7 
8 #include "events/callevents.h"
9 #include "events/filesourceinfo.h"
10 #include "events/stateevent.h"
11 
12 #include <any>
13 #include <utility>
14 
15 namespace Quotient {
16 
17 namespace EventStatus {
18  Q_NAMESPACE_EXPORT(QUOTIENT_API)
19 
20  /** Special marks an event can assume
21  *
22  * This is used to hint at a special status of some events in UI.
23  * All values except Redacted and Hidden are mutually exclusive.
24  */
25  enum Code {
26  Normal = 0x0, ///< No special designation
27  Submitted = 0x01, ///< The event has just been submitted for sending
28  FileUploaded = 0x02, ///< The file attached to the event has been
29  /// uploaded to the server
30  Departed = 0x03, ///< The event has left the client
31  ReachedServer = 0x04, ///< The server has received the event
32  SendingFailed = 0x05, ///< The server could not receive the event
33  Redacted = 0x08, ///< The event has been redacted
34  Replaced = 0x10, ///< The event has been replaced
35  Hidden = 0x100, ///< The event should not be shown in the timeline
36  };
37  Q_ENUM_NS(Code)
38 } // namespace EventStatus
39 
40 class QUOTIENT_API EventItemBase {
41 public:
42  explicit EventItemBase(RoomEventPtr&& e) : evt(std::move(e))
43  {
44  Q_ASSERT(evt);
45  }
46 
47  const RoomEvent* event() const { return std::to_address(evt); }
48  const RoomEvent* get() const { return event(); }
49  template <EventClass<RoomEvent> EventT>
50  const EventT* viewAs() const
51  {
52  return eventCast<const EventT>(evt);
53  }
54  const RoomEventPtr& operator->() const { return evt; }
55  const RoomEvent& operator*() const { return *evt; }
56 
57  // Used for event redaction
58  RoomEventPtr replaceEvent(RoomEventPtr&& other)
59  {
60  return std::exchange(evt, std::move(other));
61  }
62 
63  /// Store arbitrary data with the event item
64  void setUserData(std::any userData) { data = std::move(userData); }
65  /// Obtain custom data previously stored with the event item
66  const std::any& userdata() const { return data; }
67  std::any& userData() { return data; }
68 
69 protected:
70  template <EventClass<RoomEvent> EventT>
71  EventT* getAs()
72  {
73  return eventCast<EventT>(evt);
74  }
75 
76 private:
77  RoomEventPtr evt;
78  std::any data;
79 };
80 
81 class QUOTIENT_API TimelineItem : public EventItemBase {
82 public:
83  // For compatibility with Qt containers, even though we use
84  // a std:: container now for the room timeline
85  using index_t = int;
86 
87  TimelineItem(RoomEventPtr&& e, index_t number)
88  : EventItemBase(std::move(e)), idx(number)
89  {}
90 
91  index_t index() const { return idx; }
92 
93 private:
94  index_t idx;
95 };
96 
97 class QUOTIENT_API PendingEventItem : public EventItemBase {
98 public:
99  using EventItemBase::EventItemBase;
100 
101  EventStatus::Code deliveryStatus() const { return _status; }
102  QDateTime lastUpdated() const { return _lastUpdated; }
103  QString annotation() const { return _annotation; }
104 
105  void setDeparted() { setStatus(EventStatus::Departed); }
106  void setFileUploaded(const FileSourceInfo &uploadedFileData);
107  void setReachedServer(const QString& eventId)
108  {
109  setStatus(EventStatus::ReachedServer);
110  (*this)->addId(eventId);
111  }
112  void setSendingFailed(QString errorText)
113  {
114  setStatus(EventStatus::SendingFailed);
115  _annotation = std::move(errorText);
116  }
117  void resetStatus() { setStatus(EventStatus::Submitted); }
118 
119 private:
120  EventStatus::Code _status = EventStatus::Submitted;
121  QDateTime _lastUpdated = QDateTime::currentDateTimeUtc();
122  QString _annotation;
123 
124  void setStatus(EventStatus::Code status)
125  {
126  _status = status;
127  _lastUpdated = QDateTime::currentDateTimeUtc();
128  _annotation.clear();
129  }
130 };
131 
132 inline QDebug& operator<<(QDebug& d, const TimelineItem& ti)
133 {
134  QDebugStateSaver dss(d);
135  d.nospace() << "(" << ti.index() << "|" << ti->id() << ")";
136  return d;
137 }
138 } // namespace Quotient