1 /****************************************************************************** 2 * Copyright (C) 2018 Kitsune Ral <kitsune-ral@users.sf.net> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #pragma once 20 21 #include "events/stateevent.h" 22 23 #include <utility> 24 25 namespace Quotient { 26 class StateEventBase; 27 28 class EventStatus { 29 Q_GADGET 30 public: 31 /** Special marks an event can assume 32 * 33 * This is used to hint at a special status of some events in UI. 34 * All values except Redacted and Hidden are mutually exclusive. 35 */ 36 enum Code { 37 Normal = 0x0, //< No special designation 38 Submitted = 0x01, //< The event has just been submitted for sending 39 FileUploaded = 0x02, //< The file attached to the event has been 40 // uploaded to the server 41 Departed = 0x03, //< The event has left the client 42 ReachedServer = 0x04, //< The server has received the event 43 SendingFailed = 0x05, //< The server could not receive the event 44 Redacted = 0x08, //< The event has been redacted 45 Replaced = 0x10, //< The event has been replaced 46 Hidden = 0x100, //< The event should not be shown in the timeline 47 }; 48 Q_DECLARE_FLAGS(Status, Code) 49 Q_FLAG(Status) 50 }; 51 52 class EventItemBase { 53 public: EventItemBase(RoomEventPtr && e)54 explicit EventItemBase(RoomEventPtr&& e) : evt(std::move(e)) 55 { 56 Q_ASSERT(evt); 57 } 58 event()59 const RoomEvent* event() const { return rawPtr(evt); } get()60 const RoomEvent* get() const { return event(); } 61 template <typename EventT> viewAs()62 const EventT* viewAs() const 63 { 64 return eventCast<const EventT>(evt); 65 } 66 const RoomEventPtr& operator->() const { return evt; } 67 const RoomEvent& operator*() const { return *evt; } 68 69 // Used for event redaction replaceEvent(RoomEventPtr && other)70 RoomEventPtr replaceEvent(RoomEventPtr&& other) 71 { 72 return std::exchange(evt, move(other)); 73 } 74 75 protected: 76 template <typename EventT> getAs()77 EventT* getAs() 78 { 79 return eventCast<EventT>(evt); 80 } 81 82 private: 83 RoomEventPtr evt; 84 }; 85 86 class TimelineItem : public EventItemBase { 87 public: 88 // For compatibility with Qt containers, even though we use 89 // a std:: container now for the room timeline 90 using index_t = int; 91 TimelineItem(RoomEventPtr && e,index_t number)92 TimelineItem(RoomEventPtr&& e, index_t number) 93 : EventItemBase(std::move(e)), idx(number) 94 {} 95 index()96 index_t index() const { return idx; } 97 98 private: 99 index_t idx; 100 }; 101 102 template <> 103 inline const StateEventBase* EventItemBase::viewAs<StateEventBase>() const 104 { 105 return evt->isStateEvent() ? weakPtrCast<const StateEventBase>(evt) 106 : nullptr; 107 } 108 109 template <> 110 inline const CallEventBase* EventItemBase::viewAs<CallEventBase>() const 111 { 112 return evt->isCallEvent() ? weakPtrCast<const CallEventBase>(evt) : nullptr; 113 } 114 115 class PendingEventItem : public EventItemBase { 116 Q_GADGET 117 public: 118 using EventItemBase::EventItemBase; 119 deliveryStatus()120 EventStatus::Code deliveryStatus() const { return _status; } lastUpdated()121 QDateTime lastUpdated() const { return _lastUpdated; } annotation()122 QString annotation() const { return _annotation; } 123 setDeparted()124 void setDeparted() { setStatus(EventStatus::Departed); } 125 void setFileUploaded(const QUrl& remoteUrl); setReachedServer(const QString & eventId)126 void setReachedServer(const QString& eventId) 127 { 128 setStatus(EventStatus::ReachedServer); 129 (*this)->addId(eventId); 130 } setSendingFailed(QString errorText)131 void setSendingFailed(QString errorText) 132 { 133 setStatus(EventStatus::SendingFailed); 134 _annotation = std::move(errorText); 135 } resetStatus()136 void resetStatus() { setStatus(EventStatus::Submitted); } 137 138 private: 139 EventStatus::Code _status = EventStatus::Submitted; 140 QDateTime _lastUpdated = QDateTime::currentDateTimeUtc(); 141 QString _annotation; 142 setStatus(EventStatus::Code status)143 void setStatus(EventStatus::Code status) 144 { 145 _status = status; 146 _lastUpdated = QDateTime::currentDateTimeUtc(); 147 _annotation.clear(); 148 } 149 }; 150 151 inline QDebug& operator<<(QDebug& d, const TimelineItem& ti) 152 { 153 QDebugStateSaver dss(d); 154 d.nospace() << "(" << ti.index() << "|" << ti->id() << ")"; 155 return d; 156 } 157 } // namespace Quotient 158 Q_DECLARE_METATYPE(Quotient::EventStatus) 159