Files
neochat/src/messagecontent/CodeComponent.qml
James Graham 275d221f75 Improve time handling in NeoChat
This introduces a new NeoChatDateTime object that wraps a QDateTime. The intent is that it can be passed to QML and has a series of functions that format the QDateTime into the various string representations we need.

This means we only have to send the single object to QML and then the correct string can be grabbed from there, simplifying the backend. It is also easy to add a new representation if needed as a function with a QString output and Q_PROPERTY can be added and then it will be available.
2026-01-28 16:16:40 +00:00

192 lines
5.9 KiB
QML

// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import org.kde.syntaxhighlighting
import org.kde.neochat
QQC2.Control {
id: root
/**
* @brief The matrix ID of the message event.
*/
required property string eventId
/**
* @brief The message author.
*
* A Quotient::RoomMember object.
*
* @sa Quotient::RoomMember
*/
required property NeochatRoomMember author
/**
* @brief The timestamp of the event as a NeoChatDateTime.
*/
required property NeoChatDateTime dateTime
/**
* @brief The display text of the message.
*/
required property string display
/**
* @brief The attributes of the component.
*/
required property var componentAttributes
/**
* @brief The user selected text has changed.
*/
signal selectedTextChanged(string selectedText)
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumWidth: Message.maxContentWidth
Layout.maximumHeight: Kirigami.Units.gridUnit * 20
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
contentItem: QQC2.ScrollView {
id: codeScrollView
contentWidth: root.Message.maxContentWidth
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
QQC2.TextArea {
id: codeText
topPadding: Kirigami.Units.smallSpacing
bottomPadding: Kirigami.Units.smallSpacing
leftPadding: lineNumberColumn.width + lineNumberColumn.anchors.leftMargin + Kirigami.Units.smallSpacing * 2
text: root.display
readOnly: true
textFormat: TextEdit.PlainText
wrapMode: TextEdit.Wrap
color: Kirigami.Theme.textColor
font.family: "monospace"
font.pointSize: Kirigami.Theme.defaultFont.pointSize * NeoChatConfig.fontScale
Kirigami.SpellCheck.enabled: false
onWidthChanged: lineModel.resetModel()
onHeightChanged: lineModel.resetModel()
onSelectedTextChanged: root.selectedTextChanged(selectedText)
SyntaxHighlighter {
property string definitionName: Repository.definitionForName(root.componentAttributes.class).name
textEdit: definitionName == "None" ? null : codeText
definition: definitionName
}
ColumnLayout {
id: lineNumberColumn
anchors {
top: codeText.top
topMargin: codeText.topPadding
left: codeText.left
leftMargin: Kirigami.Units.smallSpacing
}
spacing: 0
Repeater {
id: repeater
model: LineModel {
id: lineModel
Component.onCompleted: setDocument(codeText.textDocument)
}
delegate: QQC2.Label {
id: label
required property int index
required property int docLineHeight
Layout.fillWidth: true
Layout.preferredHeight: docLineHeight
horizontalAlignment: Text.AlignRight
text: index + 1
color: Kirigami.Theme.disabledTextColor
font.family: "monospace"
}
}
}
TapHandler {
acceptedDevices: PointerDevice.TouchScreen
onLongPressed: {
const event = root.Message.room.findEvent(root.eventId);
RoomManager.viewEventMenu(root.QQC2.Overlay.overlay, event, root.Message.room, root.Message.selectedText, root.Message.hoveredLink);
}
}
background: null
}
}
Kirigami.Separator {
anchors {
top: root.top
bottom: root.bottom
left: root.left
leftMargin: lineNumberColumn.width + lineNumberColumn.anchors.leftMargin + Kirigami.Units.smallSpacing
}
}
RowLayout {
anchors {
top: parent.top
topMargin: Kirigami.Units.smallSpacing
right: parent.right
rightMargin: (codeScrollView.QQC2.ScrollBar.vertical.visible ? codeScrollView.QQC2.ScrollBar.vertical.width : 0) + Kirigami.Units.smallSpacing
}
visible: root.hovered
spacing: Kirigami.Units.mediumSpacing
QQC2.Button {
icon.name: "edit-copy"
text: i18n("Copy to clipboard")
display: QQC2.AbstractButton.IconOnly
onClicked: Clipboard.saveText(root.display);
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
QQC2.Button {
visible: root.dateTime.isValid
icon.name: "view-fullscreen"
text: i18nc("@action:button", "Maximize")
display: QQC2.AbstractButton.IconOnly
onClicked: RoomManager.maximizeCode(root.author, root.dateTime, root.display, root.componentAttributes.class);
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
}
background: Rectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
radius: Kirigami.Units.cornerRadius
border {
width: 1
color: Kirigami.Theme.highlightColor
}
}
}