summary refs log tree commit diff
path: root/src/timeline/TimelineModel.cpp
diff options
context:
space:
mode:
authorZhymabek Roman <61125068+ZhymabekRoman@users.noreply.github.com>2023-01-02 21:59:29 +0600
committerGitHub <noreply@github.com>2023-01-02 21:59:29 +0600
commit59410a99ac9b5a90356adc2192b8c6107456c78f (patch)
treef42e081641cee3d62057208f3af1de3afddd02e6 /src/timeline/TimelineModel.cpp
parentAppImage: reduce package size (diff)
parentA whole new year full of excitement and possibilities! (diff)
downloadnheko-59410a99ac9b5a90356adc2192b8c6107456c78f.tar.xz
Merge branch 'master' into master
Diffstat (limited to 'src/timeline/TimelineModel.cpp')
-rw-r--r--src/timeline/TimelineModel.cpp119
1 files changed, 110 insertions, 9 deletions
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp

index 5ffd7415..7b50da59 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2021 Nheko Contributors // SPDX-FileCopyrightText: 2022 Nheko Contributors +// SPDX-FileCopyrightText: 2023 Nheko Contributors // // SPDX-License-Identifier: GPL-3.0-or-later @@ -53,6 +54,10 @@ struct RoomEventType { return qml_mtx_events::EventType::AudioMessage; } + qml_mtx_events::EventType operator()(const mtx::events::Event<mtx::events::msg::Confetti> &) + { + return qml_mtx_events::EventType::ConfettiMessage; + } qml_mtx_events::EventType operator()(const mtx::events::Event<mtx::events::msg::Emote> &) { return qml_mtx_events::EventType::EmoteMessage; @@ -346,6 +351,7 @@ qml_mtx_events::fromRoomEventType(qml_mtx_events::EventType t) return mtx::events::EventType::SpaceChild; /// m.room.message case qml_mtx_events::AudioMessage: + case qml_mtx_events::ConfettiMessage: case qml_mtx_events::EmoteMessage: case qml_mtx_events::FileMessage: case qml_mtx_events::ImageMessage: @@ -449,6 +455,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj connect(&events, &EventStore::fetchedMore, this, [this]() { setPaginationInProgress(false); updateLastMessage(); + emit fetchedMore(); }); connect(&events, &EventStore::fetchedMore, this, &TimelineModel::checkAfterFetch); connect(&events, @@ -490,7 +497,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent); connect(this, &TimelineModel::newState, this, [this](mtx::responses::StateEvents events_) { - cache::client()->updateState(room_id_.toStdString(), events_); + cache::client()->updateState(room_id_.toStdString(), events_, true); this->syncState({std::move(events_.events)}); }); } @@ -526,6 +533,7 @@ TimelineModel::roleNames() const {IsEncrypted, "isEncrypted"}, {IsStateEvent, "isStateEvent"}, {Trustlevel, "trustlevel"}, + {Notificationlevel, "notificationlevel"}, {EncryptionError, "encryptionError"}, {ReplyTo, "replyTo"}, {ThreadId, "threadId"}, @@ -679,7 +687,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r if (w == 0) w = 1; - double prop = media_height(event) / (double)w; + double prop = (double)media_height(event) / (double)w; return {prop > 0 ? prop : 1.}; } @@ -737,6 +745,42 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r return crypto::Trust::Unverified; } + case Notificationlevel: { + const auto &push = ChatPage::instance()->pushruleEvaluator(); + if (push) { + // skip our messages + auto sender = mtx::accessors::sender(event); + if (sender == http::client()->user_id().to_string()) + return qml_mtx_events::NotificationLevel::Nothing; + + const auto &id = event_id(event); + std::vector<std::pair<mtx::common::Relation, mtx::events::collections::TimelineEvent>> + relatedEvents; + for (const auto &r : mtx::accessors::relations(event).relations) { + auto related = events.get(r.event_id, id); + if (related) { + relatedEvents.emplace_back(r, + mtx::events::collections::TimelineEvent{*related}); + } + } + + auto actions = push->evaluate({event}, pushrulesRoomContext(), relatedEvents); + if (std::find(actions.begin(), + actions.end(), + mtx::pushrules::actions::Action{ + mtx::pushrules::actions::set_tweak_highlight{}}) != actions.end()) { + return qml_mtx_events::NotificationLevel::Highlight; + } + if (std::find(actions.begin(), + actions.end(), + mtx::pushrules::actions::Action{mtx::pushrules::actions::notify{}}) != + actions.end()) { + return qml_mtx_events::NotificationLevel::Notify; + } + } + return qml_mtx_events::NotificationLevel::Nothing; + } + case EncryptionError: return events.decryptionError(event_id(event)); @@ -858,6 +902,9 @@ TimelineModel::setPaginationInProgress(const bool paginationInProgress) m_paginationInProgress = paginationInProgress; emit paginationInProgressChanged(m_paginationInProgress); + + if (m_paginationInProgress) + events.fetchMore(); } void @@ -869,8 +916,6 @@ TimelineModel::fetchMore(const QModelIndex &) } setPaginationInProgress(true); - - events.fetchMore(); } void @@ -931,6 +976,9 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) if (timeline.events.empty()) return; + if (timeline.limited) + setPaginationInProgress(false); + events.handleSync(timeline); using namespace mtx::events; @@ -991,9 +1039,18 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) } else if (std::holds_alternative<StateEvent<state::space::Parent>>(e)) { this->parentChecked = false; emit parentSpaceChanged(); - } + } else if (std::holds_alternative<RoomEvent<mtx::events::msg::Text>>(e)) { + if (auto msg = QString::fromStdString( + std::get<RoomEvent<mtx::events::msg::Text>>(e).content.body); + msg.contains("🎉") || msg.contains("🎊")) + needsSpecialEffects_ = true; + } else if (std::holds_alternative<RoomEvent<mtx::events::msg::Confetti>>(e)) + needsSpecialEffects_ = true; } + if (needsSpecialEffects_) + emit confetti(); + updateLastMessage(); } @@ -1441,7 +1498,6 @@ TimelineModel::sendEncryptedMessage(mtx::events::RoomEvent<T> msg, mtx::events:: const auto room_id = room_id_.toStdString(); using namespace mtx::events; - using namespace mtx::identifiers; nlohmann::json doc = {{"type", mtx::events::to_string(eventType)}, {"content", nlohmann::json(msg.content)}, @@ -1923,6 +1979,22 @@ TimelineModel::copyLinkToEvent(const QString &eventId) const QGuiApplication::clipboard()->setText(link); } +void +TimelineModel::triggerSpecialEffects() +{ + if (needsSpecialEffects_) { + // Note (Loren): Without the timer, this apparently emits before QML is ready + QTimer::singleShot(1, this, [this] { emit confetti(); }); + needsSpecialEffects_ = false; + } +} + +void +TimelineModel::markSpecialEffectsDone() +{ + needsSpecialEffects_ = false; +} + QString TimelineModel::formatTypingUsers(const std::vector<QString> &users, const QColor &bg) { @@ -2594,6 +2666,32 @@ TimelineModel::showAcceptKnockButton(const QString &id) return event->content.membership == Membership::Knock; } +void +TimelineModel::joinReplacementRoom(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::state::Tombstone>>(e); + if (!event) + return; + + auto joined_rooms = cache::joinedRooms(); + for (const auto &roomid : joined_rooms) { + if (roomid == event->content.replacement_room) { + manager_->rooms()->setCurrentRoom( + QString::fromStdString(event->content.replacement_room)); + return; + } + } + + ChatPage::instance()->joinRoomVia( + event->content.replacement_room, + {mtx::identifiers::parse<mtx::identifiers::User>(event->sender).hostname()}, + true); +} + QString TimelineModel::formatMemberEvent(const QString &id) { @@ -2756,7 +2854,8 @@ TimelineModel::setEdit(const QString &newEdit) auto msgType = mtx::accessors::msg_type(e); if (msgType == mtx::events::MessageType::Text || msgType == mtx::events::MessageType::Notice || - msgType == mtx::events::MessageType::Emote) { + msgType == mtx::events::MessageType::Emote || + msgType == mtx::events::MessageType::Confetti) { auto relInfo = relatedInfo(newEdit); auto editText = relInfo.quoted_body; @@ -2777,6 +2876,8 @@ TimelineModel::setEdit(const QString &newEdit) if (msgType == mtx::events::MessageType::Emote) input()->setText("/me " + editText); + else if (msgType == mtx::events::MessageType::Confetti) + input()->setText("/confetti" + editText); else input()->setText(editText); } else { @@ -2881,7 +2982,7 @@ TimelineModel::pinnedMessages() const return {}; QStringList list; - list.reserve((qsizetype)pinned->content.pinned.size()); + list.reserve((int)pinned->content.pinned.size()); for (const auto &p : pinned->content.pinned) list.push_back(QString::fromStdString(p)); @@ -2912,7 +3013,7 @@ TimelineModel::widgetLinks() const theme.clear(); user = QUrl::toPercentEncoding(user); - list.reserve((qsizetype)evs.size()); + list.reserve((int)evs.size()); for (const auto &p : evs) { auto url = QString::fromStdString(p.content.url);