|
|
|
@ -197,6 +197,12 @@ qml_mtx_events::toRoomEventType(mtx::events::EventType e) |
|
|
|
|
return qml_mtx_events::EventType::SpaceParent; |
|
|
|
|
case EventType::SpaceChild: |
|
|
|
|
return qml_mtx_events::EventType::SpaceChild; |
|
|
|
|
case EventType::ImagePackInRoom: |
|
|
|
|
return qml_mtx_events::ImagePackInRoom; |
|
|
|
|
case EventType::ImagePackInAccountData: |
|
|
|
|
return qml_mtx_events::ImagePackInAccountData; |
|
|
|
|
case EventType::ImagePackRooms: |
|
|
|
|
return qml_mtx_events::ImagePackRooms; |
|
|
|
|
case EventType::Unsupported: |
|
|
|
|
return qml_mtx_events::EventType::Unsupported; |
|
|
|
|
default: |
|
|
|
@ -2201,6 +2207,69 @@ TimelineModel::formatPowerLevelEvent(const QString &id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString |
|
|
|
|
TimelineModel::formatImagePackEvent(const QString &id) |
|
|
|
|
{ |
|
|
|
|
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); |
|
|
|
|
if (!e) |
|
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
auto event = std::get_if<mtx::events::StateEvent<mtx::events::msc2545::ImagePack>>(e); |
|
|
|
|
if (!event) |
|
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
mtx::events::StateEvent<mtx::events::msc2545::ImagePack> *prevEvent = nullptr; |
|
|
|
|
if (!event->unsigned_data.replaces_state.empty()) { |
|
|
|
|
auto tempPrevEvent = events.get(event->unsigned_data.replaces_state, event->event_id); |
|
|
|
|
if (tempPrevEvent) { |
|
|
|
|
prevEvent = |
|
|
|
|
std::get_if<mtx::events::StateEvent<mtx::events::msc2545::ImagePack>>(tempPrevEvent); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const auto &newImages = event->content.images; |
|
|
|
|
const auto oldImages = prevEvent ? prevEvent->content.images : decltype(newImages){}; |
|
|
|
|
|
|
|
|
|
auto ascent = QFontMetrics(UserSettings::instance()->font()).ascent(); |
|
|
|
|
|
|
|
|
|
auto calcChange = [ascent](const std::map<std::string, mtx::events::msc2545::PackImage> &newI, |
|
|
|
|
const std::map<std::string, mtx::events::msc2545::PackImage> &oldI) { |
|
|
|
|
QStringList added; |
|
|
|
|
for (const auto &[shortcode, img] : newI) { |
|
|
|
|
if (!oldI.count(shortcode)) |
|
|
|
|
added.push_back(QStringLiteral("<img data-mx-emoticon height=%1 src=\"%2\"> (~%3)") |
|
|
|
|
.arg(ascent) |
|
|
|
|
.arg(QString::fromStdString(img.url) |
|
|
|
|
.replace("mxc://", "image://mxcImage/") |
|
|
|
|
.toHtmlEscaped(), |
|
|
|
|
QString::fromStdString(shortcode))); |
|
|
|
|
} |
|
|
|
|
return added; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
auto added = calcChange(newImages, oldImages); |
|
|
|
|
auto removed = calcChange(oldImages, newImages); |
|
|
|
|
|
|
|
|
|
auto sender = utils::replaceEmoji(displayName(QString::fromStdString(event->sender))); |
|
|
|
|
|
|
|
|
|
QString msg; |
|
|
|
|
|
|
|
|
|
if (!removed.isEmpty()) { |
|
|
|
|
msg = tr("%1 removed the following images from the pack:<br>%2") |
|
|
|
|
.arg(sender, removed.join(", ")); |
|
|
|
|
} |
|
|
|
|
if (!added.isEmpty()) { |
|
|
|
|
if (!msg.isEmpty()) |
|
|
|
|
msg += "<br>"; |
|
|
|
|
msg += tr("%1 added the following images to the pack:<br>%2").arg(sender, added.join(", ")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (msg.isEmpty()) |
|
|
|
|
return tr("%1 changed the sticker and emotes in this room.").arg(sender); |
|
|
|
|
else |
|
|
|
|
return msg; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QVariantMap |
|
|
|
|
TimelineModel::formatRedactedEvent(const QString &id) |
|
|
|
|
{ |
|
|
|
|