summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorLoren Burkholder <55629213+LorenDB@users.noreply.github.com>2022-12-10 10:17:15 -0500
committerGitHub <noreply@github.com>2022-12-10 10:17:15 -0500
commitfa0c14b84681b94ff2136d6b7480c8b7283ad96a (patch)
tree483acc16811d00af5d13a5c196fe64f2aa3ff491 /src/timeline
parentTranslated using Weblate (French) (diff)
downloadnheko-fa0c14b84681b94ff2136d6b7480c8b7283ad96a.tar.xz
confetti (#1243)
* 🎉 (confetti) message support.  Thanks @LorenDB !
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/InputBar.cpp25
-rw-r--r--src/timeline/InputBar.h1
-rw-r--r--src/timeline/TimelineModel.cpp37
-rw-r--r--src/timeline/TimelineModel.h8
4 files changed, 69 insertions, 2 deletions
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp

index a9afb01c..94955152 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp
@@ -535,6 +535,27 @@ InputBar::notice(const QString &msg, bool rainbowify) } void +InputBar::confetti(const QString &body, bool rainbowify) +{ + auto html = utils::markdownToHtml(body, rainbowify); + + mtx::events::msg::Confetti confetti; + confetti.body = body.trimmed().toStdString(); + + if (html != body.trimmed().toHtmlEscaped() && + ChatPage::instance()->userSettings()->markdown()) { + confetti.formatted_body = html.toStdString(); + confetti.format = "org.matrix.custom.html"; + // Remove markdown links by completer + confetti.body = replaceMatrixToMarkdownLink(body.trimmed()).toStdString(); + } + + confetti.relations = generateRelations(); + + room->sendMessageEvent(confetti, mtx::events::EventType::RoomMessage); +} + +void InputBar::image(const QString &filename, const std::optional<mtx::crypto::EncryptedFile> &file, const QString &url, @@ -777,6 +798,10 @@ InputBar::command(const QString &command, QString args) notice(args, false); } else if (command == QLatin1String("rainbownotice")) { notice(args, true); + } else if (command == QLatin1String("confetti")) { + confetti(args, false); + } else if (command == QLatin1String("rainbowconfetti")) { + confetti(args, true); } else if (command == QLatin1String("goto")) { // Goto has three different modes: // 1 - Going directly to a given event ID diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h
index eced7cb8..125591d4 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h
@@ -230,6 +230,7 @@ signals: private: void emote(const QString &body, bool rainbowify); void notice(const QString &body, bool rainbowify); + void confetti(const QString &body, bool rainbowify); void command(const QString &name, QString args); void image(const QString &filename, const std::optional<mtx::crypto::EncryptedFile> &file, diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index f61214fd..fe8a78ef 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -53,6 +53,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 +350,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: @@ -1025,9 +1030,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(); } @@ -1957,6 +1971,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) { @@ -2790,7 +2820,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; @@ -2811,6 +2842,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 { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 9daeeb3a..2352be1f 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -100,6 +100,7 @@ enum EventType Widget, /// m.room.message AudioMessage, + ConfettiMessage, EmoteMessage, FileMessage, ImageMessage, @@ -419,6 +420,9 @@ public slots: QString scrollTarget() const; + void triggerSpecialEffects(); + void markSpecialEffectsDone(); + private slots: void addPendingMessage(mtx::events::collections::TimelineEvents event); void scrollTimerEvent(); @@ -438,6 +442,7 @@ signals: void paginationInProgressChanged(const bool); void newCallEvent(const mtx::events::collections::TimelineEvents &event); void scrollToIndex(int index); + void confetti(); void lastMessageChanged(); void notificationsChanged(); @@ -509,6 +514,9 @@ private: std::string last_event_id; std::string fullyReadEventId_; + // TODO (Loren): This should hopefully handle more than just confetti in the future + bool needsSpecialEffects_ = false; + std::unique_ptr<RoomSummary, DeleteLaterDeleter> parentSummary = nullptr; bool parentChecked = false; };