Show changes in image packs in timeline

This commit is contained in:
Nicolas Werner 2022-04-19 22:33:53 +02:00
parent 7138c7a49e
commit 3b2f47c56f
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
3 changed files with 72 additions and 2 deletions

View File

@ -284,11 +284,12 @@ Item {
isOnlyEmoji: false
isReply: d.isReply
isStateEvent: d.isStateEvent
formatted: qsTr("%1 changed the stickers and emotes in this room.").arg(d.userName)
formatted: d.relatedEventCacheBuster, room.formatImagePackEvent(d.eventId)
}
}
DelegateChoice {
roleValue: MtxEvent.CanonicalAlias
@ -390,7 +391,6 @@ Item {
}
DelegateChoice {
// TODO: make a more complex formatter for the power levels.
roleValue: MtxEvent.PowerLevels
NoticeMessage {

View File

@ -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)
{

View File

@ -262,6 +262,7 @@ public:
Q_INVOKABLE QString formatHistoryVisibilityEvent(const QString &id);
Q_INVOKABLE QString formatGuestAccessEvent(const QString &id);
Q_INVOKABLE QString formatPowerLevelEvent(const QString &id);
Q_INVOKABLE QString formatImagePackEvent(const QString &id);
Q_INVOKABLE QVariantMap formatRedactedEvent(const QString &id);
Q_INVOKABLE void viewRawMessage(const QString &id);