matrixion/resources/qml/Reactions.qml
Forest f66ed4bea5 Reactions: avoid highlight color misuse, subdue border color
This addresses a few problems with reaction colors:

- The state-checking conditionals for reaction text, background, and border
  were inconsistent, making it difficult to choose colors for each state
  (normal, hovered, and self reactions) that worked well in all themes.
- The QPalette::Highlight color was being misused as a text/foreground color.
  This color role is intended for background areas.  It has little contrast
  against the background in themes like KDE Plasma's Breeze High Contrast,
  so using it for text and icons makes those things difficult to read.
  https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum
- The reaction border was drawn in the same color as normal text, making it
  so bright in some dark themes that it distracted from reading nearby text.

Fixes Nheko-Reborn/nheko#1159
2022-08-19 21:14:58 -07:00

113 lines
4.3 KiB
QML

// SPDX-FileCopyrightText: 2021 Nheko Contributors
// SPDX-FileCopyrightText: 2022 Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick 2.6
import QtQuick.Controls 2.2
import im.nheko 1.0
// This class is for showing Reactions in the timeline row, not for
// adding new reactions via the emoji picker
Flow {
id: reactionFlow
// lower-contrast colors to avoid distracting from text & to enhance hover effect
property color gentleHighlight: Qt.hsla(Nheko.colors.highlight.hslHue, Nheko.colors.highlight.hslSaturation, Nheko.colors.highlight.hslLightness, 0.8)
property color gentleText: Qt.hsla(Nheko.colors.text.hslHue, Nheko.colors.text.hslSaturation, Nheko.colors.text.hslLightness, 0.6)
property string eventId
property alias reactions: repeater.model
spacing: 4
Repeater {
id: repeater
delegate: AbstractButton {
id: reaction
hoverEnabled: true
implicitWidth: contentItem.childrenRect.width + contentItem.leftPadding * 2
implicitHeight: contentItem.childrenRect.height
ToolTip.visible: hovered
ToolTip.delay: Nheko.tooltipDelay
onClicked: {
console.debug("Picked " + modelData.key + "in response to " + reactionFlow.eventId + ". selfReactedEvent: " + modelData.selfReactedEvent);
room.input.reaction(reactionFlow.eventId, modelData.key);
}
Component.onCompleted: {
ToolTip.text = Qt.binding(function() {
if (textMetrics.elidedText === textMetrics.text) {
return modelData.users;
}
return modelData.displayKey + "\n" + modelData.users;
})
}
contentItem: Row {
anchors.centerIn: parent
spacing: reactionText.implicitHeight / 4
leftPadding: reactionText.implicitHeight / 2
rightPadding: reactionText.implicitHeight / 2
TextMetrics {
id: textMetrics
font.family: Settings.emojiFont
elide: Text.ElideRight
elideWidth: 150
text: modelData.displayKey
}
Text {
id: reactionText
anchors.baseline: reactionCounter.baseline
text: {
// When an emoji font is selected that doesn't have …, it is dropped from elidedText. So we add it back.
if (textMetrics.elidedText !== modelData.displayKey) {
if (!textMetrics.elidedText.endsWith("…")) {
return textMetrics.elidedText + "…";
}
}
return textMetrics.elidedText;
}
font.family: Settings.emojiFont
color: (reaction.hovered || modelData.selfReactedEvent !== '') ? Nheko.colors.highlightedText: Nheko.colors.text
maximumLineCount: 1
}
Rectangle {
id: divider
height: Math.floor(reactionCounter.implicitHeight * 1.4)
width: 1
color: reaction.hovered ? Nheko.colors.text: gentleText
}
Text {
id: reactionCounter
anchors.verticalCenter: divider.verticalCenter
text: modelData.count
font: reaction.font
color: (reaction.hovered || modelData.selfReactedEvent !== '') ? Nheko.colors.highlightedText: Nheko.colors.windowText
}
}
background: Rectangle {
anchors.centerIn: parent
implicitWidth: reaction.implicitWidth
implicitHeight: reaction.implicitHeight
border.color: reaction.hovered ? Nheko.colors.text: gentleText
color: reaction.hovered ? Nheko.colors.highlight : (modelData.selfReactedEvent !== '' ? gentleHighlight : Nheko.colors.window)
border.width: 1
radius: reaction.height / 2
}
}
}
}