diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index b5097bc7324af4a05e260f1359cefdf9d2272547..145a82ce9127e51d345b52a2593aee6a608a80a0 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -26,6 +26,7 @@ Page { category: "user" property bool avatar_circles: true property string emoji_font_family: "default" + property double font_size: Qt.application.font.pointSize } Settings { @@ -33,6 +34,7 @@ Page { category: "user/timeline" property bool buttons: true property bool message_hover_highlight: false + property bool enlarge_emoji_only_msg: false } Menu { diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml index bef4f76d05dfcd775e37342983132d77c4e3ae65..d17723f38b662a811230f4c577b330e728f042d1 100644 --- a/resources/qml/delegates/TextMessage.qml +++ b/resources/qml/delegates/TextMessage.qml @@ -6,4 +6,5 @@ MatrixText { width: parent ? parent.width : undefined height: isReply ? Math.min(chat.height / 8, implicitHeight) : undefined clip: true + font.pointSize: (timelineSettings.enlarge_emoji_only_msg && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.font_size * 3 : settings.font_size } diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 6af08e12b90a326b0d9c2469c72b69c25525dccf..36fd768c6dbcf130e37041c75c7991b97781a0f5 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -58,6 +58,8 @@ UserSettings::load() isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool(); isMessageHoverHighlightEnabled_ = settings.value("user/timeline/message_hover_highlight", false).toBool(); + isEnlargeEmojiOnlyMessagesEnabled_ = + settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool(); isMarkdownEnabled_ = settings.value("user/markdown_enabled", true).toBool(); isTypingNotificationsEnabled_ = settings.value("user/typing_notifications", true).toBool(); sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); @@ -168,6 +170,7 @@ UserSettings::save() settings.beginGroup("timeline"); settings.setValue("buttons", isButtonsInTimelineEnabled_); settings.setValue("message_hover_highlight", isMessageHoverHighlightEnabled_); + settings.setValue("enlarge_emoji_only_msg", isEnlargeEmojiOnlyMessagesEnabled_); settings.endGroup(); settings.setValue("avatar_circles", avatarCircles_); @@ -231,22 +234,23 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge general_->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); general_->setFont(font); - trayToggle_ = new Toggle{this}; - startInTrayToggle_ = new Toggle{this}; - avatarCircles_ = new Toggle{this}; - decryptSidebar_ = new Toggle(this); - groupViewToggle_ = new Toggle{this}; - timelineButtonsToggle_ = new Toggle{this}; - typingNotifications_ = new Toggle{this}; - messageHoverHighlight_ = new Toggle{this}; - sortByImportance_ = new Toggle{this}; - readReceipts_ = new Toggle{this}; - markdownEnabled_ = new Toggle{this}; - desktopNotifications_ = new Toggle{this}; - scaleFactorCombo_ = new QComboBox{this}; - fontSizeCombo_ = new QComboBox{this}; - fontSelectionCombo_ = new QComboBox{this}; - emojiFontSelectionCombo_ = new QComboBox{this}; + trayToggle_ = new Toggle{this}; + startInTrayToggle_ = new Toggle{this}; + avatarCircles_ = new Toggle{this}; + decryptSidebar_ = new Toggle(this); + groupViewToggle_ = new Toggle{this}; + timelineButtonsToggle_ = new Toggle{this}; + typingNotifications_ = new Toggle{this}; + messageHoverHighlight_ = new Toggle{this}; + enlargeEmojiOnlyMessages_ = new Toggle{this}; + sortByImportance_ = new Toggle{this}; + readReceipts_ = new Toggle{this}; + markdownEnabled_ = new Toggle{this}; + desktopNotifications_ = new Toggle{this}; + scaleFactorCombo_ = new QComboBox{this}; + fontSizeCombo_ = new QComboBox{this}; + fontSelectionCombo_ = new QComboBox{this}; + emojiFontSelectionCombo_ = new QComboBox{this}; if (!settings_->isTrayEnabled()) startInTrayToggle_->setDisabled(true); @@ -350,6 +354,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge boxWrap(tr("Send messages as Markdown"), markdownEnabled_); boxWrap(tr("Desktop notifications"), desktopNotifications_); boxWrap(tr("Highlight message on hover"), messageHoverHighlight_); + boxWrap(tr("Large Emoji in timeline"), enlargeEmojiOnlyMessages_); formLayout_->addRow(uiLabel_); formLayout_->addRow(new HorizontalLine{this}); @@ -472,6 +477,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge settings_->setMessageHoverHighlight(!isDisabled); }); + connect(enlargeEmojiOnlyMessages_, &Toggle::toggled, this, [this](bool isDisabled) { + settings_->setEnlargeEmojiOnlyMessages(!isDisabled); + }); + connect( sessionKeysImportBtn, &QPushButton::clicked, this, &UserSettingsPage::importSessionKeys); @@ -505,6 +514,7 @@ UserSettingsPage::showEvent(QShowEvent *) markdownEnabled_->setState(!settings_->isMarkdownEnabled()); desktopNotifications_->setState(!settings_->hasDesktopNotifications()); messageHoverHighlight_->setState(!settings_->isMessageHoverHighlightEnabled()); + enlargeEmojiOnlyMessages_->setState(!settings_->isEnlargeEmojiOnlyMessagesEnabled()); deviceIdValue_->setText(QString::fromStdString(http::client()->device_id())); deviceFingerprintValue_->setText( diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 088bbfb5ff39f9883db99a03b6e21bc311edf14a..7dfa39132831c6d80453632af1ec5cf360ff1352 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -49,6 +49,11 @@ public: isMessageHoverHighlightEnabled_ = state; save(); } + void setEnlargeEmojiOnlyMessages(bool state) + { + isEnlargeEmojiOnlyMessagesEnabled_ = state; + save(); + } void setTray(bool state) { isTrayEnabled_ = state; @@ -124,6 +129,10 @@ public: QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } bool isMessageHoverHighlightEnabled() const { return isMessageHoverHighlightEnabled_; } + bool isEnlargeEmojiOnlyMessagesEnabled() const + { + return isEnlargeEmojiOnlyMessagesEnabled_; + } bool isTrayEnabled() const { return isTrayEnabled_; } bool isStartInTrayEnabled() const { return isStartInTrayEnabled_; } bool isGroupViewEnabled() const { return isGroupViewEnabled_; } @@ -151,6 +160,7 @@ private: : "system"; QString theme_; bool isMessageHoverHighlightEnabled_; + bool isEnlargeEmojiOnlyMessagesEnabled_; bool isTrayEnabled_; bool isStartInTrayEnabled_; bool isGroupViewEnabled_; @@ -211,6 +221,7 @@ private: Toggle *timelineButtonsToggle_; Toggle *typingNotifications_; Toggle *messageHoverHighlight_; + Toggle *enlargeEmojiOnlyMessages_; Toggle *sortByImportance_; Toggle *readReceipts_; Toggle *markdownEnabled_; diff --git a/src/Utils.cpp b/src/Utils.cpp index 7f11a8cdf762027bfdc97f29b283f2d1cfb0974e..d539eac5813f3db5177860c52810fcf28ea74e7e 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -51,6 +51,14 @@ utils::localUser() return QString::fromStdString(http::client()->user_id().to_string()); } +bool +utils::codepointIsEmoji(uint code) +{ + // TODO: Be more precise here. + return (code >= 0x2600 && code <= 0x27bf) || (code >= 0x1f300 && code <= 0x1f3ff) || + (code >= 0x1f000 && code <= 0x1faff); +} + QString utils::replaceEmoji(const QString &body) { @@ -63,9 +71,7 @@ utils::replaceEmoji(const QString &body) bool insideFontBlock = false; for (auto &code : utf32_string) { - // TODO: Be more precise here. - if ((code >= 0x2600 && code <= 0x27bf) || (code >= 0x1f300 && code <= 0x1f3ff) || - (code >= 0x1f000 && code <= 0x1faff)) { + if (utils::codepointIsEmoji(code)) { if (!insideFontBlock) { fmtBody += QString("<font face=\"" + userFontFamily + "\">"); insideFontBlock = true; diff --git a/src/Utils.h b/src/Utils.h index d3f6624611e0d78456910a5c31d4eb52c5b6ce2a..80f2aa7044f3e24e774d8606adf813824ab1ce8b 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -36,6 +36,9 @@ namespace utils { using TimelineEvent = mtx::events::collections::TimelineEvents; +bool +codepointIsEmoji(uint code); + QString replaceEmoji(const QString &body); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 6e653f106fcf18f11c86bd657584d8937f001bf0..6a4de92c02d891df5a50f5b7be83ff044ca44120 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -207,6 +207,7 @@ TimelineModel::roleNames() const {Section, "section"}, {Type, "type"}, {TypeString, "typeString"}, + {IsOnlyEmoji, "isOnlyEmoji"}, {Body, "body"}, {FormattedBody, "formattedBody"}, {UserId, "userId"}, @@ -272,6 +273,22 @@ TimelineModel::data(const QString &id, int role) const return QVariant(toRoomEventType(event)); case TypeString: return QVariant(toRoomEventTypeString(event)); + case IsOnlyEmoji: { + QString qBody = QString::fromStdString(body(event)); + + QVector<uint> utf32_string = qBody.toUcs4(); + int emojiCount = 0; + + for (auto &code : utf32_string) { + if (utils::codepointIsEmoji(code)) { + emojiCount++; + } else { + return QVariant(0); + } + } + + return QVariant(emojiCount); + } case Body: return QVariant(utils::replaceEmoji(QString::fromStdString(body(event)))); case FormattedBody: { @@ -374,6 +391,7 @@ TimelineModel::data(const QString &id, int role) const // m.insert(names[Section], data(id, static_cast<int>(Section))); m.insert(names[Type], data(id, static_cast<int>(Type))); m.insert(names[TypeString], data(id, static_cast<int>(TypeString))); + m.insert(names[IsOnlyEmoji], data(id, static_cast<int>(IsOnlyEmoji))); m.insert(names[Body], data(id, static_cast<int>(Body))); m.insert(names[FormattedBody], data(id, static_cast<int>(FormattedBody))); m.insert(names[UserId], data(id, static_cast<int>(UserId))); diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 0e9ddb7275c1ca448bde61b87fda0177d5913807..dc7b4985c371460e76ebb4d0a88d72f25611f5d2 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -140,6 +140,7 @@ public: Section, Type, TypeString, + IsOnlyEmoji, Body, FormattedBody, UserId,