mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Display edits correctly
This commit is contained in:
parent
faeaf9dc6b
commit
00fd4eecec
8 changed files with 99 additions and 12 deletions
|
@ -356,7 +356,7 @@ if(USE_BUNDLED_MTXCLIENT)
|
|||
FetchContent_Declare(
|
||||
MatrixClient
|
||||
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
||||
GIT_TAG 70fa15de3ec84cf0c0ab6250f2e5e62f34a6d05b
|
||||
GIT_TAG 31e300546eb63ea25b0b879fb255beee6022da03
|
||||
)
|
||||
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
||||
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
||||
|
|
|
@ -220,7 +220,7 @@
|
|||
"name": "mtxclient",
|
||||
"sources": [
|
||||
{
|
||||
"commit": "70fa15de3ec84cf0c0ab6250f2e5e62f34a6d05b",
|
||||
"commit": "31e300546eb63ea25b0b879fb255beee6022da03",
|
||||
"type": "git",
|
||||
"url": "https://github.com/Nheko-Reborn/mtxclient.git"
|
||||
}
|
||||
|
|
|
@ -85,6 +85,20 @@ Item {
|
|||
width: 16
|
||||
}
|
||||
|
||||
ImageButton {
|
||||
id: editButton
|
||||
|
||||
visible: (Settings.buttonsInTimeline && model.isEditable) || model.isEdited
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||
Layout.preferredHeight: 16
|
||||
width: 16
|
||||
hoverEnabled: true
|
||||
image: ":/icons/icons/ui/edit.png"
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: model.isEditable ? qsTr("Edit") : qsTr("Edited")
|
||||
onClicked: if (model.isEditable) chat.model.editAction(model.id)
|
||||
}
|
||||
|
||||
EmojiButton {
|
||||
id: reactButton
|
||||
|
||||
|
|
|
@ -34,6 +34,20 @@ struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
|
|||
template<template<class...> class Op, class... Args>
|
||||
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
|
||||
|
||||
struct IsStateEvent
|
||||
{
|
||||
template<class T>
|
||||
bool operator()(const mtx::events::StateEvent<T> &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
template<class T>
|
||||
bool operator()(const mtx::events::Event<T> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct EventMsgType
|
||||
{
|
||||
template<class E>
|
||||
|
@ -476,3 +490,9 @@ mtx::accessors::serialize_event(const mtx::events::collections::TimelineEvents &
|
|||
{
|
||||
return std::visit([](const auto &e) { return nlohmann::json(e); }, event);
|
||||
}
|
||||
|
||||
bool
|
||||
mtx::accessors::is_state_event(const mtx::events::collections::TimelineEvents &event)
|
||||
{
|
||||
return std::visit(IsStateEvent{}, event);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ room_id(const mtx::events::collections::TimelineEvents &event);
|
|||
std::string
|
||||
sender(const mtx::events::collections::TimelineEvents &event);
|
||||
|
||||
bool
|
||||
is_state_event(const mtx::events::collections::TimelineEvents &event);
|
||||
|
||||
QDateTime
|
||||
origin_server_ts(const mtx::events::collections::TimelineEvents &event);
|
||||
|
||||
|
|
|
@ -774,15 +774,17 @@ EventStore::get(std::string_view id, std::string_view related_to, bool decrypt,
|
|||
if (id.empty())
|
||||
return nullptr;
|
||||
|
||||
std::string id_ = std::string(id);
|
||||
IdIndex index{room_id_, std::string(id)};
|
||||
if (resolve_edits) {
|
||||
auto edits_ = edits(id_);
|
||||
if (!edits_.empty())
|
||||
id_ = mtx::accessors::event_id(edits_.back());
|
||||
auto edits_ = edits(index.id);
|
||||
if (!edits_.empty()) {
|
||||
index.id = mtx::accessors::event_id(edits_.back());
|
||||
auto event_ptr =
|
||||
new mtx::events::collections::TimelineEvents(std::move(edits_.back()));
|
||||
events_by_id_.insert(index, event_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
IdIndex index{room_id_, id_};
|
||||
|
||||
auto event_ptr = events_by_id_.object(index);
|
||||
if (!event_ptr) {
|
||||
auto event = cache::client()->getEvent(room_id_, index.id);
|
||||
|
|
|
@ -288,6 +288,8 @@ TimelineModel::roleNames() const
|
|||
{ProportionalHeight, "proportionalHeight"},
|
||||
{Id, "id"},
|
||||
{State, "state"},
|
||||
{IsEdited, "isEdited"},
|
||||
{IsEditable, "isEditable"},
|
||||
{IsEncrypted, "isEncrypted"},
|
||||
{IsRoomEncrypted, "isRoomEncrypted"},
|
||||
{ReplyTo, "replyTo"},
|
||||
|
@ -409,8 +411,12 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
|
|||
|
||||
return QVariant(prop > 0 ? prop : 1.);
|
||||
}
|
||||
case Id:
|
||||
return QVariant(QString::fromStdString(event_id(event)));
|
||||
case Id: {
|
||||
if (auto replaces = relations(event).replaces())
|
||||
return QVariant(QString::fromStdString(replaces.value()));
|
||||
else
|
||||
return QVariant(QString::fromStdString(event_id(event)));
|
||||
}
|
||||
case State: {
|
||||
auto id = QString::fromStdString(event_id(event));
|
||||
auto containsOthers = [](const auto &vec) {
|
||||
|
@ -430,6 +436,11 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
|
|||
else
|
||||
return qml_mtx_events::Received;
|
||||
}
|
||||
case IsEdited:
|
||||
return QVariant(relations(event).replaces().has_value());
|
||||
case IsEditable:
|
||||
return QVariant(!is_state_event(event) && mtx::accessors::sender(event) ==
|
||||
http::client()->user_id().to_string());
|
||||
case IsEncrypted: {
|
||||
auto id = event_id(event);
|
||||
auto encrypted_event = events.get(id, id, false);
|
||||
|
@ -444,7 +455,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
|
|||
case ReplyTo:
|
||||
return QVariant(QString::fromStdString(relations(event).reply_to().value_or("")));
|
||||
case Reactions: {
|
||||
auto id = event_id(event);
|
||||
auto id = relations(event).replaces().value_or(event_id(event));
|
||||
return QVariant::fromValue(events.reactions(id));
|
||||
}
|
||||
case RoomId:
|
||||
|
@ -813,6 +824,12 @@ TimelineModel::replyAction(QString id)
|
|||
setReply(id);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineModel::editAction(QString id)
|
||||
{
|
||||
setEdit(id);
|
||||
}
|
||||
|
||||
RelatedInfo
|
||||
TimelineModel::relatedInfo(QString id)
|
||||
{
|
||||
|
@ -1501,6 +1518,22 @@ TimelineModel::formatMemberEvent(QString id)
|
|||
return rendered;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineModel::setEdit(QString newEdit)
|
||||
{
|
||||
if (edit_ != newEdit) {
|
||||
edit_ = newEdit;
|
||||
emit editChanged(edit_);
|
||||
|
||||
auto ev = events.get(newEdit.toStdString(), "");
|
||||
if (ev) {
|
||||
setReply(QString::fromStdString(
|
||||
mtx::accessors::relations(*ev).reply_to().value_or("")));
|
||||
// input()->setText(mtx::accessors::body(*ev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
TimelineModel::roomName() const
|
||||
{
|
||||
|
|
|
@ -145,6 +145,7 @@ class TimelineModel : public QAbstractListModel
|
|||
Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY
|
||||
typingUsersChanged)
|
||||
Q_PROPERTY(QString reply READ reply WRITE setReply NOTIFY replyChanged RESET resetReply)
|
||||
Q_PROPERTY(QString edit READ edit WRITE setEdit NOTIFY editChanged RESET resetEdit)
|
||||
Q_PROPERTY(
|
||||
bool paginationInProgress READ paginationInProgress NOTIFY paginationInProgressChanged)
|
||||
Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged)
|
||||
|
@ -181,6 +182,8 @@ public:
|
|||
ProportionalHeight,
|
||||
Id,
|
||||
State,
|
||||
IsEdited,
|
||||
IsEditable,
|
||||
IsEncrypted,
|
||||
IsRoomEncrypted,
|
||||
ReplyTo,
|
||||
|
@ -213,6 +216,7 @@ public:
|
|||
Q_INVOKABLE void viewRawMessage(QString id) const;
|
||||
Q_INVOKABLE void viewDecryptedRawMessage(QString id) const;
|
||||
Q_INVOKABLE void openUserProfile(QString userid, bool global = false);
|
||||
Q_INVOKABLE void editAction(QString id);
|
||||
Q_INVOKABLE void replyAction(QString id);
|
||||
Q_INVOKABLE void readReceiptsAction(QString id) const;
|
||||
Q_INVOKABLE void redactEvent(QString id);
|
||||
|
@ -268,6 +272,16 @@ public slots:
|
|||
emit replyChanged(reply_);
|
||||
}
|
||||
}
|
||||
QString edit() const { return edit_; }
|
||||
void setEdit(QString newEdit);
|
||||
void resetEdit()
|
||||
{
|
||||
if (!edit_.isEmpty()) {
|
||||
edit_ = "";
|
||||
emit editChanged(edit_);
|
||||
resetReply();
|
||||
}
|
||||
}
|
||||
void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; }
|
||||
void clearTimeline() { events.clearTimeline(); }
|
||||
void receivedSessionKey(const std::string &session_key)
|
||||
|
@ -292,6 +306,7 @@ signals:
|
|||
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
|
||||
void typingUsersChanged(std::vector<QString> users);
|
||||
void replyChanged(QString reply);
|
||||
void editChanged(QString reply);
|
||||
void paginationInProgressChanged(const bool);
|
||||
void newCallEvent(const mtx::events::collections::TimelineEvents &event);
|
||||
|
||||
|
@ -322,7 +337,7 @@ private:
|
|||
bool m_paginationInProgress = false;
|
||||
|
||||
QString currentId;
|
||||
QString reply_;
|
||||
QString reply_, edit_;
|
||||
std::vector<QString> typingUsers_;
|
||||
|
||||
TimelineViewManager *manager_;
|
||||
|
|
Loading…
Reference in a new issue