Fix emojis in a different way
Apparently the existing fix is difficult to ship for distros. This is an alternative way, that manually goes over every text and sets the font family appropriately. Unfortunately, we need a textDocument for that, which labels don't have, meaning we have to use TextEdits instead...
This commit is contained in:
@@ -44,10 +44,6 @@ if (NOT ANDROID)
|
||||
include(KDEClangFormat)
|
||||
endif()
|
||||
|
||||
if(NEOCHAT_FLATPAK)
|
||||
include(cmake/Flatpak.cmake)
|
||||
endif()
|
||||
|
||||
ecm_setup_version(${PROJECT_VERSION}
|
||||
VARIABLE_PREFIX NEOCHAT
|
||||
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
||||
@@ -75,6 +71,13 @@ set_package_properties(Qt${QT_MAJOR_VERSION}Keychain PROPERTIES
|
||||
PURPOSE "Secure storage of account secrets"
|
||||
)
|
||||
|
||||
|
||||
find_package(ICU 61.0 COMPONENTS uc)
|
||||
set_package_properties(ICU PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Unicode library"
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
find_package(OpenSSL)
|
||||
set_package_properties(OpenSSL PROPERTIES
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Include FontConfig config which uses the Emoji One font from the
|
||||
# KDE Flatpak SDK.
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Flatpak/99-noto-mono-color-emoji.conf
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_SYSCONFDIR}/fonts/local.conf
|
||||
)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<alias>
|
||||
<family>serif</family>
|
||||
<prefer>
|
||||
<family>Noto Color Emoji</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>sans-serif</family>
|
||||
<prefer>
|
||||
<family>Noto Color Emoji</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>monospace</family>
|
||||
<prefer>
|
||||
<family>Noto Color Emoji</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
</fontconfig>
|
||||
|
||||
@@ -55,6 +55,7 @@ add_library(neochat STATIC
|
||||
events/joinrulesevent.cpp
|
||||
events/stickerevent.cpp
|
||||
models/reactionmodel.cpp
|
||||
emojifixer.cpp
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(neochat
|
||||
@@ -109,7 +110,7 @@ else()
|
||||
endif()
|
||||
|
||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
|
||||
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core)
|
||||
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core ICU::uc)
|
||||
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
|
||||
|
||||
if(NEOCHAT_FLATPAK)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <Sonnet/BackgroundChecker>
|
||||
#include <Sonnet/Settings>
|
||||
|
||||
#include "emojifixer.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
class SyntaxHighlighter : public QSyntaxHighlighter
|
||||
@@ -183,6 +184,8 @@ void ChatDocumentHandler::setDocument(QQuickTextDocument *document)
|
||||
m_document->textDocument()->disconnect(this);
|
||||
}
|
||||
m_document = document;
|
||||
static EmojiFixer emojiFixer;
|
||||
emojiFixer.addTextDocument(document);
|
||||
Q_EMIT documentChanged();
|
||||
}
|
||||
|
||||
|
||||
72
src/emojifixer.cpp
Normal file
72
src/emojifixer.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// SPDX-FileCopyrightText: Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QPalette>
|
||||
#include <QQuickTextDocument>
|
||||
#include <QTextBoundaryFinder>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextCursor>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/urename.h>
|
||||
|
||||
#include "emojifixer.h"
|
||||
|
||||
bool isEmoji(const QString &text)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void EmojiFixer::addTextDocument(QQuickTextDocument *document)
|
||||
{
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
fix(document->textDocument());
|
||||
}
|
||||
|
||||
void EmojiFixer::fix(QTextDocument *document)
|
||||
{
|
||||
disconnect(document, nullptr, this, nullptr);
|
||||
QTextCursor curs(document);
|
||||
QTextCharFormat format;
|
||||
auto font = QGuiApplication::font();
|
||||
font.setFamily("emoji");
|
||||
format.setFont(font);
|
||||
|
||||
QTextBoundaryFinder finder(QTextBoundaryFinder::Grapheme, document->toRawText());
|
||||
|
||||
int from = 0;
|
||||
while (finder.toNextBoundary() != -1) {
|
||||
auto to = finder.position();
|
||||
|
||||
auto first = document->toRawText().mid(from, to - from).toUcs4()[0];
|
||||
if (u_hasBinaryProperty(first, UCHAR_EMOJI_PRESENTATION)) {
|
||||
curs.setPosition(from, QTextCursor::MoveAnchor);
|
||||
curs.setPosition(to, QTextCursor::KeepAnchor);
|
||||
curs.setCharFormat(format);
|
||||
}
|
||||
from = to;
|
||||
}
|
||||
connect(document, &QTextDocument::contentsChanged, this, [this, document]() {
|
||||
fix(document);
|
||||
});
|
||||
}
|
||||
20
src/emojifixer.h
Normal file
20
src/emojifixer.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// SPDX-FileCopyrightText: Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QQuickTextDocument;
|
||||
class QTextDocument;
|
||||
|
||||
class EmojiFixer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void addTextDocument(QQuickTextDocument *doc);
|
||||
|
||||
private:
|
||||
void fix(QTextDocument *doc);
|
||||
};
|
||||
@@ -88,6 +88,7 @@
|
||||
#ifdef HAVE_COLORSCHEME
|
||||
#include "colorschemer.h"
|
||||
#endif
|
||||
#include "emojifixer.h"
|
||||
#include "models/completionmodel.h"
|
||||
#include "models/statemodel.h"
|
||||
#include "neochatuser.h"
|
||||
@@ -188,12 +189,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
initLogging();
|
||||
|
||||
#ifdef NEOCHAT_FLATPAK
|
||||
// Copy over the included FontConfig configuration to the
|
||||
// app's config dir:
|
||||
QFile::copy("/app/etc/fonts/conf.d/99-noto-mono-color-emoji.conf", "/var/config/fontconfig/conf.d/99-noto-mono-color-emoji.conf");
|
||||
#endif
|
||||
|
||||
Clipboard clipboard;
|
||||
auto config = NeoChatConfig::self();
|
||||
FileTypeSingleton fileTypeSingleton;
|
||||
@@ -246,6 +241,7 @@ int main(int argc, char *argv[])
|
||||
qmlRegisterType<StateModel>("org.kde.neochat", 1, 0, "StateModel");
|
||||
qmlRegisterType<StateFilterModel>("org.kde.neochat", 1, 0, "StateFilterModel");
|
||||
qmlRegisterType<SearchModel>("org.kde.neochat", 1, 0, "SearchModel");
|
||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiFixer", new EmojiFixer);
|
||||
#ifdef QUOTIENT_07
|
||||
qmlRegisterType<PollHandler>("org.kde.neochat", 1, 0, "PollHandler");
|
||||
#endif
|
||||
|
||||
@@ -165,7 +165,7 @@ ColumnLayout {
|
||||
|
||||
Component {
|
||||
id: emojiDelegate
|
||||
Kirigami.NavigationTabButton {
|
||||
NeoChatTabButton {
|
||||
width: root.categoryIconSize
|
||||
height: width
|
||||
checked: categories.currentIndex === model.index
|
||||
|
||||
92
src/qml/Component/NeoChatTabButton.qml
Normal file
92
src/qml/Component/NeoChatTabButton.qml
Normal file
@@ -0,0 +1,92 @@
|
||||
// SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Templates 2.15 as T
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
T.TabButton {
|
||||
id: control
|
||||
|
||||
property color foregroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
|
||||
property color highlightForegroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
|
||||
property color highlightBarColor: Kirigami.Theme.highlightColor
|
||||
|
||||
property color pressedColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.3)
|
||||
property color hoverSelectColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.2)
|
||||
property color checkedBorderColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.7)
|
||||
property color pressedBorderColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.9)
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
display: T.AbstractButton.TextUnderIcon
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
Kirigami.Theme.inherit: false
|
||||
|
||||
// not using the hover handler built into control, since it seems to misbehave and
|
||||
// permanently report hovered after a touch event
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
|
||||
padding: Kirigami.Units.smallSpacing
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
icon.height: control.display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
|
||||
icon.width: control.display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
|
||||
icon.color: control.checked ? control.highlightForegroundColor : control.foregroundColor
|
||||
|
||||
background: Rectangle {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
Kirigami.Theme.inherit: false
|
||||
|
||||
implicitHeight: Kirigami.Units.gridUnit * 3 + Kirigami.Units.smallSpacing * 2
|
||||
|
||||
color: "transparent"
|
||||
|
||||
Rectangle {
|
||||
width: parent.width - Kirigami.Units.largeSpacing
|
||||
height: parent.height - Kirigami.Units.largeSpacing
|
||||
anchors.centerIn: parent
|
||||
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
color: control.down ? pressedColor : (control.checked || hoverHandler.hovered ? hoverSelectColor : "transparent")
|
||||
|
||||
border.color: control.checked ? checkedBorderColor : (control.down ? pressedBorderColor : color)
|
||||
border.width: 1
|
||||
|
||||
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
|
||||
Behavior on border.color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: QQC2.Label {
|
||||
id: label
|
||||
Kirigami.MnemonicData.enabled: control.enabled && control.visible
|
||||
Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
|
||||
Kirigami.MnemonicData.label: control.text
|
||||
|
||||
text: Kirigami.MnemonicData.richTextLabel
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
wrapMode: Text.Wrap
|
||||
elide: Text.ElideMiddle
|
||||
color: control.checked ? control.highlightForegroundColor : control.foregroundColor
|
||||
|
||||
font.bold: control.checked
|
||||
font.family: "emoji"
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.20
|
||||
|
||||
Behavior on color { ColorAnimation {} }
|
||||
Behavior on opacity { NumberAnimation {} }
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Flow {
|
||||
id: root
|
||||
@@ -28,15 +29,18 @@ Flow {
|
||||
id: reactionRepeater
|
||||
model: root.model
|
||||
|
||||
delegate: QQC2.AbstractButton {
|
||||
delegate: QQC2.Control {
|
||||
width: Math.max(reactionTextMetrics.advanceWidth + Kirigami.Units.smallSpacing * 4, height)
|
||||
|
||||
contentItem: QQC2.Label {
|
||||
contentItem: TextEdit {
|
||||
id: reactionLabel
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: model.text
|
||||
|
||||
readOnly: true
|
||||
Component.onCompleted: EmojiFixer.addTextDocument(reactionLabel.textDocument)
|
||||
color: Kirigami.Theme.textColor
|
||||
selectByMouse: false
|
||||
TextMetrics {
|
||||
id: reactionTextMetrics
|
||||
text: reactionLabel.text
|
||||
@@ -56,12 +60,16 @@ Flow {
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
onClicked: reactionClicked(model.reaction)
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: reactionClicked(model.reaction)
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.text: model.toolTip
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,12 @@ TextEdit {
|
||||
|
||||
persistentSelection: true
|
||||
|
||||
// Work around QTBUG 93281
|
||||
Component.onCompleted: if (text.includes("<img")) {
|
||||
Controller.forceRefreshTextDocument(root.textDocument, root)
|
||||
Component.onCompleted: {
|
||||
EmojiFixer.addTextDocument(root.textDocument)
|
||||
// Work around QTBUG 93281
|
||||
if (text.includes("<img")) {
|
||||
Controller.forceRefreshTextDocument(root.textDocument, root)
|
||||
}
|
||||
}
|
||||
|
||||
text: "<style>
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.kde.neochat 1.0
|
||||
|
||||
import './' as RoomList
|
||||
|
||||
Kirigami.BasicListItem {
|
||||
Kirigami.AbstractListItem {
|
||||
id: root
|
||||
|
||||
required property int index
|
||||
@@ -26,7 +26,6 @@ Kirigami.BasicListItem {
|
||||
required property string subtitleText
|
||||
|
||||
required property string displayName
|
||||
|
||||
readonly property bool hasNotifications: notificationCount > 0
|
||||
|
||||
topPadding: Kirigami.Units.largeSpacing
|
||||
@@ -35,16 +34,154 @@ Kirigami.BasicListItem {
|
||||
visible: root.categoryVisible || root.filterText.length > 0 || Config.mergeRoomList
|
||||
highlighted: ListView.view.currentIndex === index
|
||||
focus: true
|
||||
icon: undefined
|
||||
bold: root.hasNotifications
|
||||
property bool bold: root.hasNotifications
|
||||
|
||||
label: root.displayName
|
||||
labelItem.textFormat: Text.PlainText
|
||||
contentItem: Item {
|
||||
id: contItem
|
||||
|
||||
subtitle: root.subtitleText
|
||||
subtitleItem {
|
||||
textFormat: Text.PlainText
|
||||
visible: !Config.compactRoomList
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
||||
Binding on implicitHeight {
|
||||
value: Math.max(iconItem.size, (!subtitleItem.visible && root.reserveSpaceForSubtitle ? (labelItem.implicitHeight + labelColumn.spacing + subtitleItem.implicitHeight): labelColumn.implicitHeight) )
|
||||
delayed: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
spacing: LayoutMirroring.enabled ? root.rightPadding : root.leftPadding
|
||||
anchors.left: contItem.left
|
||||
anchors.leftMargin: root.leading ? root.leadingPadding : 0
|
||||
anchors.right: contItem.right
|
||||
anchors.rightMargin: root.trailing ? root.trailingPadding : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Kirigami.Avatar {
|
||||
source: root.avatar ? `image://mxc/${root.avatar}` : ""
|
||||
name: root.displayName
|
||||
implicitWidth: visible ? height : 0
|
||||
visible: Config.showAvatarInRoomDrawer
|
||||
Layout.preferredWidth: sourceSize.width
|
||||
Layout.preferredHeight: sourceSize.height
|
||||
sourceSize {
|
||||
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: iconItem
|
||||
source: root.icon.name !== "" ? root.icon.name : root.icon.source
|
||||
property int size: subtitleItem.visible || reserveSpaceForSubtitle ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.smallMedium
|
||||
Layout.minimumHeight: size
|
||||
Layout.maximumHeight: size
|
||||
Layout.minimumWidth: size
|
||||
Layout.maximumWidth: size
|
||||
selected: (root.highlighted || root.checked || root.down)
|
||||
opacity: root.fadeContent ? 0.6 : 1.0
|
||||
visible: source.toString() !== ""
|
||||
}
|
||||
ColumnLayout {
|
||||
id: labelColumn
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
TextEdit {
|
||||
id: labelItem
|
||||
text: labelMetrics.elidedText
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: subtitleItem.visible ? Qt.AlignLeft | Qt.AlignBottom : Qt.AlignLeft | Qt.AlignVCenter
|
||||
color: (root.highlighted || root.checked || root.down) ? root.activeTextColor : root.textColor
|
||||
font.weight: root.bold ? Font.Bold : Font.Normal
|
||||
opacity: root.fadeContent ? 0.6 : 1.0
|
||||
readOnly: true
|
||||
Component.onCompleted: EmojiFixer.addTextDocument(labelItem.textDocument)
|
||||
TextMetrics {
|
||||
id: labelMetrics
|
||||
font: labelItem.font
|
||||
text: root.displayName
|
||||
elideWidth: labelItem.width
|
||||
elide: Qt.ElideRight
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: RoomManager.enterRoom(root.currentRoom)
|
||||
onPressAndHold: createRoomListContextMenu()
|
||||
}
|
||||
}
|
||||
TextEdit {
|
||||
id: subtitleItem
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: subtitleItem.visible ? Qt.AlignLeft | Qt.AlignTop : Qt.AlignLeft | Qt.AlignVCenter
|
||||
color: (root.highlighted || root.checked || root.down) ? root.activeTextColor : root.textColor
|
||||
//elide: Text.ElideRight
|
||||
font: Kirigami.Theme.smallFont
|
||||
opacity: root.fadeContent ? 0.6 : (root.bold ? 0.9 : 0.7)
|
||||
text: subtitleMetrics.elidedText
|
||||
textFormat: Text.PlainText
|
||||
visible: !Config.compactRoomList
|
||||
readOnly: true
|
||||
Component.onCompleted: EmojiFixer.addTextDocument(subtitleItem.textDocument)
|
||||
TextMetrics {
|
||||
id: subtitleMetrics
|
||||
font: subtitleItem.font
|
||||
text: root.subtitleText
|
||||
elideWidth: subtitleItem.width
|
||||
elide: Qt.ElideRight
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: RoomManager.enterRoom(root.currentRoom)
|
||||
onPressAndHold: createRoomListContextMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.Icon {
|
||||
source: "notifications-disabled"
|
||||
enabled: false
|
||||
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
||||
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
||||
visible: currentRoom.pushNotificationState === PushNotificationState.Mute && !configButton.visible && !hasNotifications
|
||||
Accessible.name: i18n("Muted room")
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
}
|
||||
QQC2.Label {
|
||||
id: notificationCountLabel
|
||||
text: notificationCount
|
||||
visible: hasNotifications
|
||||
color: Kirigami.Theme.textColor
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
background: Rectangle {
|
||||
visible: notificationCount > 0
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
color: highlightCount > 0 ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.disabledTextColor
|
||||
opacity: highlightCount > 0 ? 1 : 0.3
|
||||
radius: height / 2
|
||||
}
|
||||
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
Layout.minimumHeight: Kirigami.Units.iconSizes.smallMedium
|
||||
Layout.minimumWidth: Math.max(notificationCountTextMetrics.advanceWidth + Kirigami.Units.smallSpacing * 2, height)
|
||||
|
||||
TextMetrics {
|
||||
id: notificationCountTextMetrics
|
||||
text: notificationCountLabel.text
|
||||
}
|
||||
}
|
||||
QQC2.Button {
|
||||
id: configButton
|
||||
visible: root.hovered && !Kirigami.Settings.isMobile && !Config.compactRoomList
|
||||
text: i18n("Configure room")
|
||||
display: QQC2.Button.IconOnly
|
||||
|
||||
icon.name: "configure"
|
||||
onClicked: createRoomListContextMenu()
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
acceptedDevices: PointerDevice.Mouse
|
||||
onTapped: createRoomListContextMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: RoomManager.enterRoom(root.currentRoom)
|
||||
@@ -53,67 +190,6 @@ Kirigami.BasicListItem {
|
||||
Keys.onEnterPressed: RoomManager.enterRoom(root.currentRoom)
|
||||
Keys.onReturnPressed: RoomManager.enterRoom(root.currentRoom)
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
acceptedDevices: PointerDevice.Mouse
|
||||
onTapped: createRoomListContextMenu()
|
||||
}
|
||||
|
||||
leading: Kirigami.Avatar {
|
||||
source: root.avatar ? `image://mxc/${root.avatar}` : ""
|
||||
name: root.displayName
|
||||
implicitWidth: visible ? height : 0
|
||||
visible: Config.showAvatarInRoomDrawer
|
||||
sourceSize {
|
||||
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||
}
|
||||
}
|
||||
|
||||
trailing: RowLayout {
|
||||
Kirigami.Icon {
|
||||
source: "notifications-disabled"
|
||||
enabled: false
|
||||
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
||||
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
||||
visible: currentRoom.pushNotificationState === PushNotificationState.Mute && !configButton.visible && !hasNotifications
|
||||
Accessible.name: i18n("Muted room")
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
}
|
||||
QQC2.Label {
|
||||
id: notificationCountLabel
|
||||
text: notificationCount
|
||||
visible: hasNotifications
|
||||
color: Kirigami.Theme.textColor
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
background: Rectangle {
|
||||
visible: notificationCount > 0
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
color: highlightCount > 0 ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.disabledTextColor
|
||||
opacity: highlightCount > 0 ? 1 : 0.3
|
||||
radius: height / 2
|
||||
}
|
||||
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
Layout.minimumHeight: Kirigami.Units.iconSizes.smallMedium
|
||||
Layout.minimumWidth: Math.max(notificationCountTextMetrics.advanceWidth + Kirigami.Units.smallSpacing * 2, height)
|
||||
|
||||
TextMetrics {
|
||||
id: notificationCountTextMetrics
|
||||
text: notificationCountLabel.text
|
||||
}
|
||||
}
|
||||
QQC2.Button {
|
||||
id: configButton
|
||||
visible: root.hovered && !Kirigami.Settings.isMobile && !Config.compactRoomList
|
||||
text: i18n("Configure room")
|
||||
display: QQC2.Button.IconOnly
|
||||
|
||||
icon.name: "configure"
|
||||
onClicked: createRoomListContextMenu()
|
||||
}
|
||||
}
|
||||
|
||||
function createRoomListContextMenu() {
|
||||
const component = Qt.createComponent(Qt.resolvedUrl("./ContextMenu.qml"))
|
||||
const menu = component.createObject(root, {
|
||||
|
||||
@@ -92,6 +92,7 @@ ColumnLayout {
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
|
||||
}
|
||||
background: Item {}
|
||||
Component.onCompleted: EmojiFixer.addTextDocument(topicText.textDocument)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
<file alias="TimelineView.qml">qml/Component/TimelineView.qml</file>
|
||||
<file alias="InvitationView.qml">qml/Component/InvitationView.qml</file>
|
||||
<file alias="AvatarTabButton.qml">qml/Component/AvatarTabButton.qml</file>
|
||||
<file alias="NeoChatTabButton.qml">qml/Component/NeoChatTabButton.qml</file>
|
||||
<file alias="SpaceDrawer.qml">qml/Page/RoomList/SpaceDrawer.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
Reference in New Issue
Block a user