|
|
@ -144,72 +144,96 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj |
|
|
|
, room_id_(room_id) |
|
|
|
, room_id_(room_id) |
|
|
|
, manager_(manager) |
|
|
|
, manager_(manager) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
connect(this, |
|
|
|
|
|
|
|
&TimelineModel::oldMessagesRetrieved, |
|
|
|
|
|
|
|
this, |
|
|
|
|
|
|
|
&TimelineModel::addBackwardsEvents, |
|
|
|
|
|
|
|
Qt::QueuedConnection); |
|
|
|
connect( |
|
|
|
connect( |
|
|
|
this, &TimelineModel::oldMessagesRetrieved, this, &TimelineModel::addBackwardsEvents); |
|
|
|
this, |
|
|
|
connect(this, &TimelineModel::messageFailed, this, [this](QString txn_id) { |
|
|
|
&TimelineModel::messageFailed, |
|
|
|
nhlog::ui()->error("Failed to send {}, retrying", txn_id.toStdString()); |
|
|
|
this, |
|
|
|
|
|
|
|
[this](QString txn_id) { |
|
|
|
QTimer::singleShot(5000, this, [this]() { emit nextPendingMessage(); }); |
|
|
|
nhlog::ui()->error("Failed to send {}, retrying", txn_id.toStdString()); |
|
|
|
}); |
|
|
|
|
|
|
|
connect(this, &TimelineModel::messageSent, this, [this](QString txn_id, QString event_id) { |
|
|
|
|
|
|
|
pending.removeOne(txn_id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto ev = events.value(txn_id); |
|
|
|
QTimer::singleShot(5000, this, [this]() { emit nextPendingMessage(); }); |
|
|
|
|
|
|
|
}, |
|
|
|
if (auto reaction = |
|
|
|
Qt::QueuedConnection); |
|
|
|
std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(&ev)) { |
|
|
|
connect( |
|
|
|
QString reactedTo = |
|
|
|
this, |
|
|
|
QString::fromStdString(reaction->content.relates_to.event_id); |
|
|
|
&TimelineModel::messageSent, |
|
|
|
auto &rModel = reactions[reactedTo]; |
|
|
|
this, |
|
|
|
rModel.removeReaction(*reaction); |
|
|
|
[this](QString txn_id, QString event_id) { |
|
|
|
auto rCopy = *reaction; |
|
|
|
pending.removeOne(txn_id); |
|
|
|
rCopy.event_id = event_id.toStdString(); |
|
|
|
|
|
|
|
rModel.addReaction(room_id_.toStdString(), rCopy); |
|
|
|
auto ev = events.value(txn_id); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (auto reaction = |
|
|
|
int idx = idToIndex(txn_id); |
|
|
|
std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(&ev)) { |
|
|
|
if (idx < 0) { |
|
|
|
QString reactedTo = |
|
|
|
// transaction already received via sync
|
|
|
|
QString::fromStdString(reaction->content.relates_to.event_id); |
|
|
|
return; |
|
|
|
auto &rModel = reactions[reactedTo]; |
|
|
|
} |
|
|
|
rModel.removeReaction(*reaction); |
|
|
|
eventOrder[idx] = event_id; |
|
|
|
auto rCopy = *reaction; |
|
|
|
ev = std::visit( |
|
|
|
rCopy.event_id = event_id.toStdString(); |
|
|
|
[event_id](const auto &e) -> mtx::events::collections::TimelineEvents { |
|
|
|
rModel.addReaction(room_id_.toStdString(), rCopy); |
|
|
|
auto eventCopy = e; |
|
|
|
} |
|
|
|
eventCopy.event_id = event_id.toStdString(); |
|
|
|
|
|
|
|
return eventCopy; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
ev); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
events.remove(txn_id); |
|
|
|
int idx = idToIndex(txn_id); |
|
|
|
events.insert(event_id, ev); |
|
|
|
if (idx < 0) { |
|
|
|
|
|
|
|
// transaction already received via sync
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
eventOrder[idx] = event_id; |
|
|
|
|
|
|
|
ev = std::visit( |
|
|
|
|
|
|
|
[event_id](const auto &e) -> mtx::events::collections::TimelineEvents { |
|
|
|
|
|
|
|
auto eventCopy = e; |
|
|
|
|
|
|
|
eventCopy.event_id = event_id.toStdString(); |
|
|
|
|
|
|
|
return eventCopy; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
ev); |
|
|
|
|
|
|
|
|
|
|
|
// mark our messages as read
|
|
|
|
events.remove(txn_id); |
|
|
|
readEvent(event_id.toStdString()); |
|
|
|
events.insert(event_id, ev); |
|
|
|
|
|
|
|
|
|
|
|
emit dataChanged(index(idx, 0), index(idx, 0)); |
|
|
|
// mark our messages as read
|
|
|
|
|
|
|
|
readEvent(event_id.toStdString()); |
|
|
|
|
|
|
|
|
|
|
|
if (pending.size() > 0) |
|
|
|
emit dataChanged(index(idx, 0), index(idx, 0)); |
|
|
|
emit nextPendingMessage(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
connect(this, &TimelineModel::redactionFailed, this, [](const QString &msg) { |
|
|
|
|
|
|
|
emit ChatPage::instance()->showNotification(msg); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pending.size() > 0) |
|
|
|
|
|
|
|
emit nextPendingMessage(); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Qt::QueuedConnection); |
|
|
|
connect( |
|
|
|
connect( |
|
|
|
this, &TimelineModel::nextPendingMessage, this, &TimelineModel::processOnePendingMessage); |
|
|
|
this, |
|
|
|
connect(this, &TimelineModel::newMessageToSend, this, &TimelineModel::addPendingMessage); |
|
|
|
&TimelineModel::redactionFailed, |
|
|
|
|
|
|
|
this, |
|
|
|
|
|
|
|
[](const QString &msg) { emit ChatPage::instance()->showNotification(msg); }, |
|
|
|
|
|
|
|
Qt::QueuedConnection); |
|
|
|
|
|
|
|
|
|
|
|
connect(this, |
|
|
|
connect(this, |
|
|
|
&TimelineModel::eventFetched, |
|
|
|
&TimelineModel::nextPendingMessage, |
|
|
|
this, |
|
|
|
this, |
|
|
|
[this](QString requestingEvent, mtx::events::collections::TimelineEvents event) { |
|
|
|
&TimelineModel::processOnePendingMessage, |
|
|
|
events.insert(QString::fromStdString(mtx::accessors::event_id(event)), |
|
|
|
Qt::QueuedConnection); |
|
|
|
event); |
|
|
|
connect(this, |
|
|
|
auto idx = idToIndex(requestingEvent); |
|
|
|
&TimelineModel::newMessageToSend, |
|
|
|
if (idx >= 0) |
|
|
|
this, |
|
|
|
emit dataChanged(index(idx, 0), index(idx, 0)); |
|
|
|
&TimelineModel::addPendingMessage, |
|
|
|
}); |
|
|
|
Qt::QueuedConnection); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connect( |
|
|
|
|
|
|
|
this, |
|
|
|
|
|
|
|
&TimelineModel::eventFetched, |
|
|
|
|
|
|
|
this, |
|
|
|
|
|
|
|
[this](QString requestingEvent, mtx::events::collections::TimelineEvents event) { |
|
|
|
|
|
|
|
events.insert(QString::fromStdString(mtx::accessors::event_id(event)), event); |
|
|
|
|
|
|
|
auto idx = idToIndex(requestingEvent); |
|
|
|
|
|
|
|
if (idx >= 0) |
|
|
|
|
|
|
|
emit dataChanged(index(idx, 0), index(idx, 0)); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Qt::QueuedConnection); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QHash<int, QByteArray> |
|
|
|
QHash<int, QByteArray> |
|
|
|