new chatlistview component, file attachments, performance & primitive test
This commit is contained in:
@@ -16,10 +16,15 @@ CustomRect {
|
||||
property bool copied: false
|
||||
property color codeBackgroundColor: Colors.palette.m3surfaceContainerHigh
|
||||
property color codeHeaderColor: Colors.palette.m3outline
|
||||
property var codeSpans: []
|
||||
property string html: ""
|
||||
property bool colored: false
|
||||
property string requestedCode: ""
|
||||
property string requestedLanguage: ""
|
||||
property int highlightToken: 0
|
||||
|
||||
function refresh() {
|
||||
requestedCode = root.code;
|
||||
requestedLanguage = root.language;
|
||||
const token = ++root.highlightToken;
|
||||
CodeHighlighter.highlight(root.code, root.language, root, token);
|
||||
}
|
||||
@@ -27,7 +32,11 @@ CustomRect {
|
||||
function onHighlightSpans(token, spans) {
|
||||
if (token !== root.highlightToken)
|
||||
return;
|
||||
codeSpans = spans;
|
||||
if (root.code !== root.requestedCode ||
|
||||
root.language !== root.requestedLanguage)
|
||||
return;
|
||||
html = spans.length ? root.highlightedHtml(root.code, spans) : "";
|
||||
colored = root.visible && html.length > 0;
|
||||
}
|
||||
|
||||
function roleColor(kind) {
|
||||
@@ -71,6 +80,21 @@ CustomRect {
|
||||
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
// Mirrors the whitespace rules of the rich text rendering below (leading
|
||||
// whitespace kept, mid-line runs collapsed, tabs as single spaces) so the
|
||||
// plain and colored layouts are identical.
|
||||
function plainForDisplay(code): string {
|
||||
return code.split("\n")
|
||||
.map(line => {
|
||||
const i = line.search(/\S/);
|
||||
if (i < 0)
|
||||
return "";
|
||||
const lead = line.slice(0, i).replace(/\t/g, " ");
|
||||
return lead + line.slice(i).replace(/\s+/g, " ").replace(/\s+$/, "");
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function highlightedHtml(code, spans): string {
|
||||
let out;
|
||||
if (!spans.length) {
|
||||
@@ -101,10 +125,26 @@ CustomRect {
|
||||
radius: Tokens.rounding.medium
|
||||
|
||||
onLanguageChanged: {
|
||||
codeSpans = [];
|
||||
refresh();
|
||||
html = "";
|
||||
colored = false;
|
||||
if (root.visible)
|
||||
refreshTimer.restart();
|
||||
}
|
||||
onCodeChanged: {
|
||||
colored = false;
|
||||
if (root.visible)
|
||||
refreshTimer.restart();
|
||||
}
|
||||
onVisibleChanged: if (root.visible)
|
||||
refreshTimer.restart();
|
||||
|
||||
Timer {
|
||||
id: refreshTimer
|
||||
|
||||
interval: 200
|
||||
repeat: false
|
||||
onTriggered: refresh()
|
||||
}
|
||||
onCodeChanged: refresh()
|
||||
|
||||
RowLayout {
|
||||
id: headerRow
|
||||
@@ -229,21 +269,6 @@ CustomRect {
|
||||
implicitHeight: codeText.implicitHeight + codeFlick.anchors.margins * 2
|
||||
color: CodeColors.active.bg
|
||||
|
||||
CustomText {
|
||||
id: code
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
x: implicitWidth * (0 - codeFlick.visibleArea.xPosition) + Tokens.padding.small
|
||||
anchors.margins: Tokens.padding.small
|
||||
text: root.highlightedHtml(root.code, root.codeSpans)
|
||||
textFormat: Text.RichText
|
||||
color: CodeColors.active.normal
|
||||
layer.enabled: true
|
||||
clip: false
|
||||
font.family: Config.appearance.font.family.mono
|
||||
font.pointSize: Tokens.font.size.small
|
||||
}
|
||||
|
||||
Flickable {
|
||||
id: codeFlick
|
||||
|
||||
@@ -263,12 +288,11 @@ CustomRect {
|
||||
|
||||
color: CodeColors.active.normal
|
||||
layer.enabled: true
|
||||
leftInset: Tokens.padding.small
|
||||
clip: false
|
||||
font.family: Config.appearance.font.family.mono
|
||||
font.pointSize: Tokens.font.size.small
|
||||
textFormat: Text.RichText
|
||||
text: code.text
|
||||
textFormat: root.colored ? Text.RichText : Text.PlainText
|
||||
text: root.colored ? root.html : root.plainForDisplay(root.code)
|
||||
readOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user