Colorful emoji in reaction
Use ICU to determine if the string contains only emojis
This commit is contained in:
@@ -63,9 +63,9 @@ set_package_properties(KF6 PROPERTIES
|
||||
PURPOSE "Basic application components"
|
||||
)
|
||||
set_package_properties(KF6Kirigami2 PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Kirigami application UI framework"
|
||||
)
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Kirigami application UI framework"
|
||||
)
|
||||
find_package(KF6KirigamiAddons 0.7.2 REQUIRED)
|
||||
|
||||
if(ANDROID)
|
||||
@@ -81,6 +81,12 @@ else()
|
||||
TYPE RUNTIME
|
||||
)
|
||||
ecm_find_qmlmodule(org.kde.syntaxhighlighting 1.0)
|
||||
|
||||
find_package(ICU 61.0 COMPONENTS uc)
|
||||
set_package_properties(ICU PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Unicode library"
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||
|
||||
@@ -319,9 +319,10 @@ if(NOT ANDROID)
|
||||
else()
|
||||
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
|
||||
endif()
|
||||
target_link_libraries(neochat PUBLIC KF6::ConfigWidgets KF6::WindowSystem)
|
||||
target_link_libraries(neochat PUBLIC KF6::ConfigWidgets KF6::WindowSystem ICU::uc)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_WINDOWSYSTEM)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_ICU)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
#include "reactionmodel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#ifdef HAVE_ICU
|
||||
#include <QTextBoundaryFinder>
|
||||
#include <QTextCharFormat>
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/urename.h>
|
||||
#endif
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
@@ -29,11 +35,38 @@ QVariant ReactionModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
const auto &reaction = m_reactions.at(index.row());
|
||||
|
||||
if (role == TextRole) {
|
||||
const auto isEmoji = [](const QString &text) {
|
||||
#ifdef HAVE_ICU
|
||||
QTextBoundaryFinder finder(QTextBoundaryFinder::Grapheme, text);
|
||||
int from = 0;
|
||||
while (finder.toNextBoundary() != -1) {
|
||||
auto to = finder.position();
|
||||
if (text[from].isSpace()) {
|
||||
from = to;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto first = text.mid(from, to - from).toUcs4()[0];
|
||||
if (!u_hasBinaryProperty(first, UCHAR_EMOJI_PRESENTATION)) {
|
||||
return false;
|
||||
}
|
||||
from = to;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
};
|
||||
|
||||
const auto reactionText = isEmoji(reaction.reaction)
|
||||
? QStringLiteral("<span style=\"font-family: 'emoji';\">") + reaction.reaction + QStringLiteral("</span>")
|
||||
: reaction.reaction;
|
||||
|
||||
if (role == TextContentRole) {
|
||||
if (reaction.authors.count() > 1) {
|
||||
return QStringLiteral("%1 %2").arg(reaction.reaction, QString::number(reaction.authors.count()));
|
||||
return QStringLiteral("%1 %2").arg(reactionText, QString::number(reaction.authors.count()));
|
||||
} else {
|
||||
return reaction.reaction;
|
||||
return reactionText;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +97,7 @@ QVariant ReactionModel::data(const QModelIndex &index, int role) const
|
||||
"%2 reacted with %3",
|
||||
reaction.authors.count(),
|
||||
text,
|
||||
reaction.reaction);
|
||||
reactionText);
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -101,7 +134,7 @@ void ReactionModel::setReactions(QList<Reaction> reactions)
|
||||
QHash<int, QByteArray> ReactionModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{TextRole, "text"},
|
||||
{TextContentRole, "textContent"},
|
||||
{ReactionRole, "reaction"},
|
||||
{ToolTipRole, "toolTip"},
|
||||
{AuthorsRole, "authors"},
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
* @brief Defines the model roles.
|
||||
*/
|
||||
enum Roles {
|
||||
TextRole = Qt::DisplayRole, /**< The text to show in the reaction. */
|
||||
TextContentRole = Qt::DisplayRole, /**< The text to show in the reaction. */
|
||||
ReactionRole, /**< The reaction emoji. */
|
||||
ToolTipRole, /**< The tool tip to show for the reaction. */
|
||||
AuthorsRole, /**< The list of authors who sent the given reaction. */
|
||||
|
||||
@@ -28,39 +28,45 @@ Flow {
|
||||
id: reactionRepeater
|
||||
|
||||
delegate: QQC2.AbstractButton {
|
||||
width: Math.max(reactionTextMetrics.advanceWidth + Kirigami.Units.smallSpacing * 4, height)
|
||||
id: reactionDelegate
|
||||
|
||||
required property string textContent
|
||||
required property string reaction
|
||||
required property string toolTip
|
||||
required property bool hasLocalUser
|
||||
|
||||
width: Math.max(contentItem.implicitWidth + leftPadding + rightPadding, height)
|
||||
height: Math.round(Kirigami.Units.gridUnit * 1.5)
|
||||
|
||||
contentItem: QQC2.Label {
|
||||
id: reactionLabel
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: model.text
|
||||
|
||||
TextMetrics {
|
||||
id: reactionTextMetrics
|
||||
text: reactionLabel.text
|
||||
}
|
||||
text: reactionDelegate.textContent
|
||||
background: null
|
||||
wrapMode: TextEdit.NoWrap
|
||||
textFormat: Text.RichText
|
||||
}
|
||||
|
||||
padding: Kirigami.Units.smallSpacing
|
||||
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
color: model.hasLocalUser ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor
|
||||
color: reactionDelegate.hasLocalUser ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
radius: height / 2
|
||||
shadow {
|
||||
size: Kirigami.Units.smallSpacing
|
||||
color: !model.hasLocalUser ? Qt.rgba(0.0, 0.0, 0.0, 0.10) : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10)
|
||||
color: !reactionDelegate.hasLocalUser ? Qt.rgba(0.0, 0.0, 0.0, 0.10) : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10)
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: reactionClicked(model.reaction)
|
||||
onClicked: reactionClicked(reactionDelegate.reaction)
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.text: model.toolTip
|
||||
QQC2.ToolTip.text: reactionDelegate.toolTip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user