Make sure that the content model is loaded properly when a new event is set. This fixes seeing an unknown event message for all new events. Instead a loading symbol is briefly seen before switching to the actual content.
This commit is contained in:
@@ -34,7 +34,7 @@ MessageContentModel::MessageContentModel(NeoChatRoom *room, const QString &event
|
|||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
, m_room(room)
|
, m_room(room)
|
||||||
, m_eventId(eventId)
|
, m_eventId(eventId)
|
||||||
, m_isPending(isPending)
|
, m_currentState(isPending ? Pending : Unknown)
|
||||||
, m_isReply(isReply)
|
, m_isReply(isReply)
|
||||||
{
|
{
|
||||||
initializeModel();
|
initializeModel();
|
||||||
@@ -45,19 +45,27 @@ void MessageContentModel::initializeModel()
|
|||||||
Q_ASSERT(m_room != nullptr);
|
Q_ASSERT(m_room != nullptr);
|
||||||
Q_ASSERT(!m_eventId.isEmpty());
|
Q_ASSERT(!m_eventId.isEmpty());
|
||||||
|
|
||||||
connect(this, &MessageContentModel::eventUnavailable, this, &MessageContentModel::getEvent);
|
connect(m_room, &NeoChatRoom::pendingEventAdded, this, [this]() {
|
||||||
|
if (m_room != nullptr && m_currentState == Unknown) {
|
||||||
|
initializeEvent();
|
||||||
|
updateReplyModel();
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
|
});
|
||||||
connect(m_room, &NeoChatRoom::pendingEventAboutToMerge, this, [this](Quotient::RoomEvent *serverEvent) {
|
connect(m_room, &NeoChatRoom::pendingEventAboutToMerge, this, [this](Quotient::RoomEvent *serverEvent) {
|
||||||
if (m_room != nullptr) {
|
if (m_room != nullptr) {
|
||||||
if (m_eventId == serverEvent->id() || m_eventId == serverEvent->transactionId()) {
|
if (m_eventId == serverEvent->id() || m_eventId == serverEvent->transactionId()) {
|
||||||
beginResetModel();
|
|
||||||
m_isPending = false;
|
|
||||||
m_eventId = serverEvent->id();
|
m_eventId = serverEvent->id();
|
||||||
initializeEvent();
|
|
||||||
endResetModel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(m_room, &NeoChatRoom::pendingEventMerged, this, [this]() {
|
||||||
|
if (m_room != nullptr && m_currentState == Pending) {
|
||||||
|
initializeEvent();
|
||||||
|
updateReplyModel();
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
|
});
|
||||||
connect(m_room, &NeoChatRoom::addedMessages, this, [this](int fromIndex, int toIndex) {
|
connect(m_room, &NeoChatRoom::addedMessages, this, [this](int fromIndex, int toIndex) {
|
||||||
if (m_room != nullptr) {
|
if (m_room != nullptr) {
|
||||||
for (int i = fromIndex; i <= toIndex; i++) {
|
for (int i = fromIndex; i <= toIndex; i++) {
|
||||||
@@ -143,20 +151,33 @@ void MessageContentModel::initializeModel()
|
|||||||
});
|
});
|
||||||
|
|
||||||
initializeEvent();
|
initializeEvent();
|
||||||
updateReplyModel();
|
if (m_currentState == Available || m_currentState == Pending) {
|
||||||
resetModel();
|
updateReplyModel();
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageContentModel::initializeEvent()
|
void MessageContentModel::initializeEvent()
|
||||||
{
|
{
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
if (m_currentState == UnAvailable) {
|
||||||
if (event == nullptr) {
|
|
||||||
Q_EMIT eventUnavailable();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto eventResult = m_room->getEvent(m_eventId);
|
||||||
|
if (eventResult.first == nullptr) {
|
||||||
|
if (m_currentState != Pending) {
|
||||||
|
getEvent();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (eventResult.second) {
|
||||||
|
m_currentState = Pending;
|
||||||
|
} else {
|
||||||
|
m_currentState = Available;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_eventSenderObject == nullptr) {
|
if (m_eventSenderObject == nullptr) {
|
||||||
auto senderId = event->senderId();
|
auto senderId = eventResult.first->senderId();
|
||||||
// A pending event might not have a sender ID set yet but in that case it must
|
// A pending event might not have a sender ID set yet but in that case it must
|
||||||
// be the local member.
|
// be the local member.
|
||||||
if (senderId.isEmpty()) {
|
if (senderId.isEmpty()) {
|
||||||
@@ -172,7 +193,6 @@ void MessageContentModel::getEvent()
|
|||||||
Quotient::connectUntil(m_room.get(), &NeoChatRoom::extraEventLoaded, this, [this](const QString &eventId) {
|
Quotient::connectUntil(m_room.get(), &NeoChatRoom::extraEventLoaded, this, [this](const QString &eventId) {
|
||||||
if (m_room != nullptr) {
|
if (m_room != nullptr) {
|
||||||
if (eventId == m_eventId) {
|
if (eventId == m_eventId) {
|
||||||
m_notFound = false;
|
|
||||||
initializeEvent();
|
initializeEvent();
|
||||||
updateReplyModel();
|
updateReplyModel();
|
||||||
resetModel();
|
resetModel();
|
||||||
@@ -184,7 +204,7 @@ void MessageContentModel::getEvent()
|
|||||||
Quotient::connectUntil(m_room.get(), &NeoChatRoom::extraEventNotFound, this, [this](const QString &eventId) {
|
Quotient::connectUntil(m_room.get(), &NeoChatRoom::extraEventNotFound, this, [this](const QString &eventId) {
|
||||||
if (m_room != nullptr) {
|
if (m_room != nullptr) {
|
||||||
if (eventId == m_eventId) {
|
if (eventId == m_eventId) {
|
||||||
m_notFound = true;
|
m_currentState = UnAvailable;
|
||||||
resetModel();
|
resetModel();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -237,7 +257,7 @@ QVariant MessageContentModel::data(const QModelIndex &index, int role) const
|
|||||||
const auto component = m_components[index.row()];
|
const auto component = m_components[index.row()];
|
||||||
|
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
const auto event = m_room->getEvent(m_eventId);
|
||||||
if (event == nullptr) {
|
if (event.first == nullptr) {
|
||||||
if (role == DisplayRole) {
|
if (role == DisplayRole) {
|
||||||
if (m_isReply) {
|
if (m_isReply) {
|
||||||
return i18n("Loading reply");
|
return i18n("Loading reply");
|
||||||
@@ -252,7 +272,7 @@ QVariant MessageContentModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (role == DisplayRole) {
|
if (role == DisplayRole) {
|
||||||
if (m_notFound || m_room->connection()->isIgnored(m_eventSenderId)) {
|
if (m_currentState == UnAvailable || m_room->connection()->isIgnored(m_eventSenderId)) {
|
||||||
Kirigami::Platform::PlatformTheme *theme =
|
Kirigami::Platform::PlatformTheme *theme =
|
||||||
static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true));
|
static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true));
|
||||||
|
|
||||||
@@ -276,7 +296,7 @@ QVariant MessageContentModel::data(const QModelIndex &index, int role) const
|
|||||||
if (!component.content.isEmpty()) {
|
if (!component.content.isEmpty()) {
|
||||||
return component.content;
|
return component.content;
|
||||||
}
|
}
|
||||||
return EventHandler::richBody(m_room, event);
|
return EventHandler::richBody(m_room, event.first);
|
||||||
}
|
}
|
||||||
if (role == ComponentTypeRole) {
|
if (role == ComponentTypeRole) {
|
||||||
return component.type;
|
return component.type;
|
||||||
@@ -285,53 +305,53 @@ QVariant MessageContentModel::data(const QModelIndex &index, int role) const
|
|||||||
return component.attributes;
|
return component.attributes;
|
||||||
}
|
}
|
||||||
if (role == EventIdRole) {
|
if (role == EventIdRole) {
|
||||||
return EventHandler::id(event);
|
return EventHandler::id(event.first);
|
||||||
}
|
}
|
||||||
if (role == TimeRole) {
|
if (role == TimeRole) {
|
||||||
const auto pendingIt = std::find_if(m_room->pendingEvents().cbegin(), m_room->pendingEvents().cend(), [event](const PendingEventItem &pendingEvent) {
|
const auto pendingIt = std::find_if(m_room->pendingEvents().cbegin(), m_room->pendingEvents().cend(), [event](const PendingEventItem &pendingEvent) {
|
||||||
return event->transactionId() == pendingEvent->transactionId();
|
return event.first->transactionId() == pendingEvent->transactionId();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto lastUpdated = pendingIt == m_room->pendingEvents().cend() ? QDateTime() : pendingIt->lastUpdated();
|
auto lastUpdated = pendingIt == m_room->pendingEvents().cend() ? QDateTime() : pendingIt->lastUpdated();
|
||||||
return EventHandler::time(event, m_isPending, lastUpdated);
|
return EventHandler::time(event.first, m_currentState == Pending, lastUpdated);
|
||||||
}
|
}
|
||||||
if (role == TimeStringRole) {
|
if (role == TimeStringRole) {
|
||||||
const auto pendingIt = std::find_if(m_room->pendingEvents().cbegin(), m_room->pendingEvents().cend(), [event](const PendingEventItem &pendingEvent) {
|
const auto pendingIt = std::find_if(m_room->pendingEvents().cbegin(), m_room->pendingEvents().cend(), [event](const PendingEventItem &pendingEvent) {
|
||||||
return event->transactionId() == pendingEvent->transactionId();
|
return event.first->transactionId() == pendingEvent->transactionId();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto lastUpdated = pendingIt == m_room->pendingEvents().cend() ? QDateTime() : pendingIt->lastUpdated();
|
auto lastUpdated = pendingIt == m_room->pendingEvents().cend() ? QDateTime() : pendingIt->lastUpdated();
|
||||||
return EventHandler::timeString(event, QStringLiteral("hh:mm"), m_isPending, lastUpdated);
|
return EventHandler::timeString(event.first, QStringLiteral("hh:mm"), m_currentState == Pending, lastUpdated);
|
||||||
}
|
}
|
||||||
if (role == AuthorRole) {
|
if (role == AuthorRole) {
|
||||||
return QVariant::fromValue<NeochatRoomMember *>(m_eventSenderObject.get());
|
return QVariant::fromValue<NeochatRoomMember *>(m_eventSenderObject.get());
|
||||||
}
|
}
|
||||||
if (role == MediaInfoRole) {
|
if (role == MediaInfoRole) {
|
||||||
return EventHandler::mediaInfo(m_room, event);
|
return EventHandler::mediaInfo(m_room, event.first);
|
||||||
}
|
}
|
||||||
if (role == FileTransferInfoRole) {
|
if (role == FileTransferInfoRole) {
|
||||||
return QVariant::fromValue(m_room->cachedFileTransferInfo(event));
|
return QVariant::fromValue(m_room->cachedFileTransferInfo(event.first));
|
||||||
}
|
}
|
||||||
if (role == ItineraryModelRole) {
|
if (role == ItineraryModelRole) {
|
||||||
return QVariant::fromValue<ItineraryModel *>(m_itineraryModel);
|
return QVariant::fromValue<ItineraryModel *>(m_itineraryModel);
|
||||||
}
|
}
|
||||||
if (role == LatitudeRole) {
|
if (role == LatitudeRole) {
|
||||||
return EventHandler::latitude(event);
|
return EventHandler::latitude(event.first);
|
||||||
}
|
}
|
||||||
if (role == LongitudeRole) {
|
if (role == LongitudeRole) {
|
||||||
return EventHandler::longitude(event);
|
return EventHandler::longitude(event.first);
|
||||||
}
|
}
|
||||||
if (role == AssetRole) {
|
if (role == AssetRole) {
|
||||||
return EventHandler::locationAssetType(event);
|
return EventHandler::locationAssetType(event.first);
|
||||||
}
|
}
|
||||||
if (role == PollHandlerRole) {
|
if (role == PollHandlerRole) {
|
||||||
return QVariant::fromValue<PollHandler *>(m_room->poll(m_eventId));
|
return QVariant::fromValue<PollHandler *>(m_room->poll(m_eventId));
|
||||||
}
|
}
|
||||||
if (role == ReplyEventIdRole) {
|
if (role == ReplyEventIdRole) {
|
||||||
return EventHandler::replyId(event);
|
return EventHandler::replyId(event.first);
|
||||||
}
|
}
|
||||||
if (role == ReplyAuthorRole) {
|
if (role == ReplyAuthorRole) {
|
||||||
return QVariant::fromValue(EventHandler::replyAuthor(m_room, event));
|
return QVariant::fromValue(EventHandler::replyAuthor(m_room, event.first));
|
||||||
}
|
}
|
||||||
if (role == ReplyContentModelRole) {
|
if (role == ReplyContentModelRole) {
|
||||||
return QVariant::fromValue<MessageContentModel *>(m_replyModel);
|
return QVariant::fromValue<MessageContentModel *>(m_replyModel);
|
||||||
@@ -387,18 +407,17 @@ QHash<int, QByteArray> MessageContentModel::roleNames() const
|
|||||||
|
|
||||||
void MessageContentModel::resetModel()
|
void MessageContentModel::resetModel()
|
||||||
{
|
{
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
|
||||||
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_components.clear();
|
m_components.clear();
|
||||||
|
|
||||||
if (m_room->connection()->isIgnored(m_eventSenderId) || m_notFound) {
|
if (m_room->connection()->isIgnored(m_eventSenderId) || m_currentState == UnAvailable) {
|
||||||
m_components += MessageComponent{MessageComponentType::Text, QString(), {}};
|
m_components += MessageComponent{MessageComponentType::Text, QString(), {}};
|
||||||
endResetModel();
|
endResetModel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == nullptr) {
|
const auto event = m_room->getEvent(m_eventId);
|
||||||
|
if (event.first == nullptr) {
|
||||||
m_components += MessageComponent{MessageComponentType::Loading, QString(), {}};
|
m_components += MessageComponent{MessageComponentType::Loading, QString(), {}};
|
||||||
endResetModel();
|
endResetModel();
|
||||||
return;
|
return;
|
||||||
@@ -431,19 +450,19 @@ void MessageContentModel::resetContent(bool isEditing, bool isThreading)
|
|||||||
QList<MessageComponent> MessageContentModel::messageContentComponents(bool isEditing, bool isThreading)
|
QList<MessageComponent> MessageContentModel::messageContentComponents(bool isEditing, bool isThreading)
|
||||||
{
|
{
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
const auto event = m_room->getEvent(m_eventId);
|
||||||
if (event == nullptr) {
|
if (event.first == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<MessageComponent> newComponents;
|
QList<MessageComponent> newComponents;
|
||||||
|
|
||||||
if (eventCast<const Quotient::RoomMessageEvent>(event)
|
if (eventCast<const Quotient::RoomMessageEvent>(event.first)
|
||||||
&& eventCast<const Quotient::RoomMessageEvent>(event)->rawMsgtype() == QStringLiteral("m.key.verification.request")) {
|
&& eventCast<const Quotient::RoomMessageEvent>(event.first)->rawMsgtype() == QStringLiteral("m.key.verification.request")) {
|
||||||
newComponents += MessageComponent{MessageComponentType::Verification, QString(), {}};
|
newComponents += MessageComponent{MessageComponentType::Verification, QString(), {}};
|
||||||
return newComponents;
|
return newComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->isRedacted()) {
|
if (event.first->isRedacted()) {
|
||||||
newComponents += MessageComponent{MessageComponentType::Text, QString(), {}};
|
newComponents += MessageComponent{MessageComponentType::Text, QString(), {}};
|
||||||
return newComponents;
|
return newComponents;
|
||||||
}
|
}
|
||||||
@@ -455,7 +474,7 @@ QList<MessageComponent> MessageContentModel::messageContentComponents(bool isEdi
|
|||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
newComponents += MessageComponent{MessageComponentType::ChatBar, QString(), {}};
|
newComponents += MessageComponent{MessageComponentType::ChatBar, QString(), {}};
|
||||||
} else {
|
} else {
|
||||||
newComponents.append(componentsForType(MessageComponentType::typeForEvent(*event)));
|
newComponents.append(componentsForType(MessageComponentType::typeForEvent(*event.first)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_room->urlPreviewEnabled()) {
|
if (m_room->urlPreviewEnabled()) {
|
||||||
@@ -463,7 +482,7 @@ QList<MessageComponent> MessageContentModel::messageContentComponents(bool isEdi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the event is already threaded the ThreadModel will handle displaying a chat bar.
|
// If the event is already threaded the ThreadModel will handle displaying a chat bar.
|
||||||
if (isThreading && !EventHandler::isThreaded(event)) {
|
if (isThreading && !EventHandler::isThreaded(event.first)) {
|
||||||
newComponents += MessageComponent{MessageComponentType::ChatBar, QString(), {}};
|
newComponents += MessageComponent{MessageComponentType::ChatBar, QString(), {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,11 +492,11 @@ QList<MessageComponent> MessageContentModel::messageContentComponents(bool isEdi
|
|||||||
void MessageContentModel::updateReplyModel()
|
void MessageContentModel::updateReplyModel()
|
||||||
{
|
{
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
const auto event = m_room->getEvent(m_eventId);
|
||||||
if (event == nullptr || m_isReply) {
|
if (event.first == nullptr || m_isReply) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EventHandler::hasReply(event) || (EventHandler::isThreaded(event) && NeoChatConfig::self()->threads())) {
|
if (!EventHandler::hasReply(event.first) || (EventHandler::isThreaded(event.first) && NeoChatConfig::self()->threads())) {
|
||||||
if (m_replyModel) {
|
if (m_replyModel) {
|
||||||
delete m_replyModel;
|
delete m_replyModel;
|
||||||
}
|
}
|
||||||
@@ -488,7 +507,7 @@ void MessageContentModel::updateReplyModel()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_replyModel = new MessageContentModel(m_room, EventHandler::replyId(event), true, false, this);
|
m_replyModel = new MessageContentModel(m_room, EventHandler::replyId(event.first), true, false, this);
|
||||||
|
|
||||||
connect(m_replyModel, &MessageContentModel::eventUpdated, this, [this]() {
|
connect(m_replyModel, &MessageContentModel::eventUpdated, this, [this]() {
|
||||||
Q_EMIT dataChanged(index(0), index(0), {ReplyAuthorRole});
|
Q_EMIT dataChanged(index(0), index(0), {ReplyAuthorRole});
|
||||||
@@ -498,13 +517,13 @@ void MessageContentModel::updateReplyModel()
|
|||||||
QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentType::Type type)
|
QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentType::Type type)
|
||||||
{
|
{
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
const auto event = m_room->getEvent(m_eventId);
|
||||||
if (event == nullptr) {
|
if (event.first == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MessageComponentType::Text: {
|
case MessageComponentType::Text: {
|
||||||
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event);
|
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event.first);
|
||||||
auto body = EventHandler::rawMessageBody(*roomMessageEvent);
|
auto body = EventHandler::rawMessageBody(*roomMessageEvent);
|
||||||
return TextHandler().textComponents(body,
|
return TextHandler().textComponents(body,
|
||||||
EventHandler::messageBodyInputFormat(*roomMessageEvent),
|
EventHandler::messageBodyInputFormat(*roomMessageEvent),
|
||||||
@@ -515,11 +534,11 @@ QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentT
|
|||||||
case MessageComponentType::File: {
|
case MessageComponentType::File: {
|
||||||
QList<MessageComponent> components;
|
QList<MessageComponent> components;
|
||||||
components += MessageComponent{MessageComponentType::File, QString(), {}};
|
components += MessageComponent{MessageComponentType::File, QString(), {}};
|
||||||
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event);
|
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event.first);
|
||||||
|
|
||||||
if (m_emptyItinerary) {
|
if (m_emptyItinerary) {
|
||||||
if (!m_isReply) {
|
if (!m_isReply) {
|
||||||
auto fileTransferInfo = m_room->cachedFileTransferInfo(event);
|
auto fileTransferInfo = m_room->cachedFileTransferInfo(event.first);
|
||||||
|
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
Q_ASSERT(roomMessageEvent->content() != nullptr && roomMessageEvent->has<EventContent::FileContent>());
|
Q_ASSERT(roomMessageEvent->content() != nullptr && roomMessageEvent->has<EventContent::FileContent>());
|
||||||
@@ -567,8 +586,8 @@ QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentT
|
|||||||
case MessageComponentType::Image:
|
case MessageComponentType::Image:
|
||||||
case MessageComponentType::Audio:
|
case MessageComponentType::Audio:
|
||||||
case MessageComponentType::Video: {
|
case MessageComponentType::Video: {
|
||||||
if (!event->is<StickerEvent>()) {
|
if (!event.first->is<StickerEvent>()) {
|
||||||
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event);
|
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event.first);
|
||||||
QList<MessageComponent> components;
|
QList<MessageComponent> components;
|
||||||
components += MessageComponent{type, QString(), {}};
|
components += MessageComponent{type, QString(), {}};
|
||||||
auto body = EventHandler::rawMessageBody(*roomMessageEvent);
|
auto body = EventHandler::rawMessageBody(*roomMessageEvent);
|
||||||
@@ -653,13 +672,13 @@ void MessageContentModel::closeLinkPreview(int row)
|
|||||||
void MessageContentModel::updateItineraryModel()
|
void MessageContentModel::updateItineraryModel()
|
||||||
{
|
{
|
||||||
const auto event = m_room->getEvent(m_eventId);
|
const auto event = m_room->getEvent(m_eventId);
|
||||||
if (m_room == nullptr || event == nullptr) {
|
if (m_room == nullptr || event.first == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event)) {
|
if (auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event.first)) {
|
||||||
if (roomMessageEvent->has<EventContent::FileContent>()) {
|
if (roomMessageEvent->has<EventContent::FileContent>()) {
|
||||||
auto filePath = m_room->cachedFileTransferInfo(event).localPath;
|
auto filePath = m_room->cachedFileTransferInfo(event.first).localPath;
|
||||||
if (filePath.isEmpty() && m_itineraryModel != nullptr) {
|
if (filePath.isEmpty() && m_itineraryModel != nullptr) {
|
||||||
delete m_itineraryModel;
|
delete m_itineraryModel;
|
||||||
m_itineraryModel = nullptr;
|
m_itineraryModel = nullptr;
|
||||||
|
|||||||
@@ -31,6 +31,14 @@ class MessageContentModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(bool showAuthor READ showAuthor WRITE setShowAuthor NOTIFY showAuthorChanged)
|
Q_PROPERTY(bool showAuthor READ showAuthor WRITE setShowAuthor NOTIFY showAuthorChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum MessageState {
|
||||||
|
Unknown, /**< The message state is unknown. */
|
||||||
|
Pending, /**< The message is a new pending message which the server has not yet acknowledged. */
|
||||||
|
Available, /**< The message is available and acknowledged by the server. */
|
||||||
|
UnAvailable, /**< The message can't be retrieved either because it doesn't exist or is blocked. */
|
||||||
|
};
|
||||||
|
Q_ENUM(MessageState)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the model roles.
|
* @brief Defines the model roles.
|
||||||
*/
|
*/
|
||||||
@@ -98,7 +106,6 @@ public:
|
|||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void showAuthorChanged();
|
void showAuthorChanged();
|
||||||
void eventUnavailable();
|
|
||||||
void eventUpdated();
|
void eventUpdated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -107,10 +114,9 @@ private:
|
|||||||
QString m_eventSenderId;
|
QString m_eventSenderId;
|
||||||
std::unique_ptr<NeochatRoomMember> m_eventSenderObject = nullptr;
|
std::unique_ptr<NeochatRoomMember> m_eventSenderObject = nullptr;
|
||||||
|
|
||||||
bool m_isPending;
|
MessageState m_currentState = Unknown;
|
||||||
bool m_showAuthor = true;
|
bool m_showAuthor = true;
|
||||||
bool m_isReply;
|
bool m_isReply;
|
||||||
bool m_notFound = false;
|
|
||||||
|
|
||||||
void initializeModel();
|
void initializeModel();
|
||||||
void initializeEvent();
|
void initializeEvent();
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
|
|||||||
});
|
});
|
||||||
connect(m_currentRoom, &Room::pendingEventAboutToAdd, this, [this](Quotient::RoomEvent *event) {
|
connect(m_currentRoom, &Room::pendingEventAboutToAdd, this, [this](Quotient::RoomEvent *event) {
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
createEventObjects(event);
|
createEventObjects(event, true);
|
||||||
beginInsertRows({}, 0, 0);
|
beginInsertRows({}, 0, 0);
|
||||||
});
|
});
|
||||||
connect(m_currentRoom, &Room::pendingEventAdded, this, &MessageEventModel::endInsertRows);
|
connect(m_currentRoom, &Room::pendingEventAdded, this, &MessageEventModel::endInsertRows);
|
||||||
@@ -618,7 +618,7 @@ int MessageEventModel::eventIdToRow(const QString &eventID) const
|
|||||||
return it - m_currentRoom->messageEvents().rbegin() + timelineBaseIndex();
|
return it - m_currentRoom->messageEvents().rbegin() + timelineBaseIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageEventModel::createEventObjects(const Quotient::RoomEvent *event)
|
void MessageEventModel::createEventObjects(const Quotient::RoomEvent *event, bool isPending)
|
||||||
{
|
{
|
||||||
if (event == nullptr) {
|
if (event == nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -641,7 +641,7 @@ void MessageEventModel::createEventObjects(const Quotient::RoomEvent *event)
|
|||||||
|
|
||||||
if (!m_contentModels.contains(eventId) && !m_contentModels.contains(event->transactionId())) {
|
if (!m_contentModels.contains(eventId) && !m_contentModels.contains(event->transactionId())) {
|
||||||
if (!event->isStateEvent() || event->matrixType() == QStringLiteral("org.matrix.msc3672.beacon_info")) {
|
if (!event->isStateEvent() || event->matrixType() == QStringLiteral("org.matrix.msc3672.beacon_info")) {
|
||||||
m_contentModels[eventId] = std::unique_ptr<MessageContentModel>(new MessageContentModel(m_currentRoom, eventId));
|
m_contentModels[eventId] = std::unique_ptr<MessageContentModel>(new MessageContentModel(m_currentRoom, eventId, false, isPending));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ private:
|
|||||||
int refreshEventRoles(const QString &eventId, const QList<int> &roles = {});
|
int refreshEventRoles(const QString &eventId, const QList<int> &roles = {});
|
||||||
void moveReadMarker(const QString &toEventId);
|
void moveReadMarker(const QString &toEventId);
|
||||||
|
|
||||||
void createEventObjects(const Quotient::RoomEvent *event);
|
void createEventObjects(const Quotient::RoomEvent *event, bool isPending = false);
|
||||||
// Hack to ensure that we don't call endInsertRows when we haven't called beginInsertRows
|
// Hack to ensure that we don't call endInsertRows when we haven't called beginInsertRows
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1749,25 +1749,31 @@ void NeoChatRoom::downloadEventFromServer(const QString &eventId)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomEvent *NeoChatRoom::getEvent(const QString &eventId) const
|
std::pair<const Quotient::RoomEvent *, bool> NeoChatRoom::getEvent(const QString &eventId) const
|
||||||
{
|
{
|
||||||
if (eventId.isEmpty()) {
|
if (eventId.isEmpty()) {
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
const auto timelineIt = findInTimeline(eventId);
|
const auto timelineIt = findInTimeline(eventId);
|
||||||
if (timelineIt != historyEdge()) {
|
if (timelineIt != historyEdge()) {
|
||||||
return timelineIt->get();
|
return std::make_pair(timelineIt->get(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pendingIt = findPendingEvent(eventId);
|
auto pendingIt = findPendingEvent(eventId);
|
||||||
if (pendingIt != pendingEvents().end()) {
|
if (pendingIt != pendingEvents().end()) {
|
||||||
return pendingIt->event();
|
return std::make_pair(pendingIt->event(), true);
|
||||||
|
}
|
||||||
|
// findPendingEvent() searches by transaction ID, we also need to check event ID.
|
||||||
|
for (const auto &event : pendingEvents()) {
|
||||||
|
if (event->id() == eventId || event->transactionId() == eventId) {
|
||||||
|
return std::make_pair(event.event(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto extraIt = std::find_if(m_extraEvents.begin(), m_extraEvents.end(), [eventId](const Quotient::event_ptr_tt<Quotient::RoomEvent> &event) {
|
auto extraIt = std::find_if(m_extraEvents.begin(), m_extraEvents.end(), [eventId](const Quotient::event_ptr_tt<Quotient::RoomEvent> &event) {
|
||||||
return event->id() == eventId;
|
return event->id() == eventId;
|
||||||
});
|
});
|
||||||
return extraIt != m_extraEvents.end() ? extraIt->get() : nullptr;
|
return std::make_pair(extraIt != m_extraEvents.end() ? extraIt->get() : nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomEvent *NeoChatRoom::getReplyForEvent(const RoomEvent &event) const
|
const RoomEvent *NeoChatRoom::getReplyForEvent(const RoomEvent &event) const
|
||||||
|
|||||||
@@ -570,7 +570,7 @@ public:
|
|||||||
*
|
*
|
||||||
* The result will be nullptr if not found so needs to be managed.
|
* The result will be nullptr if not found so needs to be managed.
|
||||||
*/
|
*/
|
||||||
const Quotient::RoomEvent *getEvent(const QString &eventId) const;
|
std::pair<const Quotient::RoomEvent *, bool> getEvent(const QString &eventId) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply.
|
* @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply.
|
||||||
|
|||||||
Reference in New Issue
Block a user